Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf evsel: Do not put a variable sized type not at the end of a struct

As this is a GNU extension and while harmless in this case, we can do
the same thing in a more clearer way by using a existing thread_map and
cpu_map constructors:

With this we avoid this while compiling with clang:

util/evsel.c:1659:17: error: field 'map' with variable sized type 'struct cpu_map' not at the end of a struct or class is a GNU extension
[-Werror,-Wgnu-variable-sized-type-not-at-end]
struct cpu_map map;
^
util/evsel.c:1667:20: error: field 'map' with variable sized type 'struct thread_map' not at the end of a struct or class is a GNU extension
[-Werror,-Wgnu-variable-sized-type-not-at-end]
struct thread_map map;
^
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-207juvrqjiar7uvas2s83v5i@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

+28 -34
+28 -34
tools/perf/util/evsel.c
··· 1448 1448 return true; 1449 1449 } 1450 1450 1451 - static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, 1452 - struct thread_map *threads) 1451 + int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, 1452 + struct thread_map *threads) 1453 1453 { 1454 1454 int cpu, thread, nthreads; 1455 1455 unsigned long flags = PERF_FLAG_FD_CLOEXEC; ··· 1458 1458 1459 1459 if (perf_missing_features.write_backward && evsel->attr.write_backward) 1460 1460 return -EINVAL; 1461 + 1462 + if (cpus == NULL) { 1463 + static struct cpu_map *empty_cpu_map; 1464 + 1465 + if (empty_cpu_map == NULL) { 1466 + empty_cpu_map = cpu_map__dummy_new(); 1467 + if (empty_cpu_map == NULL) 1468 + return -ENOMEM; 1469 + } 1470 + 1471 + cpus = empty_cpu_map; 1472 + } 1473 + 1474 + if (threads == NULL) { 1475 + static struct thread_map *empty_thread_map; 1476 + 1477 + if (empty_thread_map == NULL) { 1478 + empty_thread_map = thread_map__new_by_tid(-1); 1479 + if (empty_thread_map == NULL) 1480 + return -ENOMEM; 1481 + } 1482 + 1483 + threads = empty_thread_map; 1484 + } 1461 1485 1462 1486 if (evsel->system_wide) 1463 1487 nthreads = 1; ··· 1679 1655 perf_evsel__free_fd(evsel); 1680 1656 } 1681 1657 1682 - static struct { 1683 - struct cpu_map map; 1684 - int cpus[1]; 1685 - } empty_cpu_map = { 1686 - .map.nr = 1, 1687 - .cpus = { -1, }, 1688 - }; 1689 - 1690 - static struct { 1691 - struct thread_map map; 1692 - int threads[1]; 1693 - } empty_thread_map = { 1694 - .map.nr = 1, 1695 - .threads = { -1, }, 1696 - }; 1697 - 1698 - int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, 1699 - struct thread_map *threads) 1700 - { 1701 - if (cpus == NULL) { 1702 - /* Work around old compiler warnings about strict aliasing */ 1703 - cpus = &empty_cpu_map.map; 1704 - } 1705 - 1706 - if (threads == NULL) 1707 - threads = &empty_thread_map.map; 1708 - 1709 - return __perf_evsel__open(evsel, cpus, threads); 1710 - } 1711 - 1712 1658 int perf_evsel__open_per_cpu(struct perf_evsel *evsel, 1713 1659 struct cpu_map *cpus) 1714 1660 { 1715 - return __perf_evsel__open(evsel, cpus, &empty_thread_map.map); 1661 + return perf_evsel__open(evsel, cpus, NULL); 1716 1662 } 1717 1663 1718 1664 int perf_evsel__open_per_thread(struct perf_evsel *evsel, 1719 1665 struct thread_map *threads) 1720 1666 { 1721 - return __perf_evsel__open(evsel, &empty_cpu_map.map, threads); 1667 + return perf_evsel__open(evsel, NULL, threads); 1722 1668 } 1723 1669 1724 1670 static int perf_evsel__parse_id_sample(const struct perf_evsel *evsel,