[Bug ipa/97364] New: Clarify/improve documentation for __attribute__ ((pure))
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97364 Bug ID: 97364 Summary: Clarify/improve documentation for __attribute__ ((pure)) Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: ipa Assignee: unassigned at gcc dot gnu.org Reporter: m...@nieper-wisskirchen.de CC: marxin at gcc dot gnu.org Target Milestone: --- The documentation of the `pure' function attribute currently says: "Calls to functions that have no observable effects on the state of the program other than to return a value may lend themselves to optimizations such as common subexpression elimination. Declaring such functions with the pure attribute allows GCC to avoid emitting some calls in repeated invocations of the function with the same argument values. The pure attribute prohibits a function from modifying the state of the program that is observable by means other than inspecting the function’s return value. However, functions declared with the pure attribute can safely read any non-volatile objects, and modify the value of objects in a way that does not affect their return value or the observable state of the program." Unfortunately, the documentation is silent on the issue of a function possibly not returning at all (say, due to an assert macro checking the function arguments). For example, GCC currently suggest to add the `pure' function attribute to the function `gl_linked_iterator_from_to' ([1]) of Gnulib. To me, this seems correct despite the call to `abort', but it is not completely clear from the wording of GCC's documentation. Gnulib doesn't want to silence the warning from -Wsuggest-attribute=pure by adding the `pure' attribute by hand without being sure that it would be indeed correct. Which also leads to the question: How to silence the warning in case the function is *not* pure? Thanks, Marc -- [1] http://git.savannah.gnu.org/cgit/gnulib.git/tree/lib/gl_anylinked_list2.h#n938
[Bug jit/105279] New: Using libgccjit produces a null pointer access in GCC's tree-optimization code
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105279 Bug ID: 105279 Summary: Using libgccjit produces a null pointer access in GCC's tree-optimization code Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: jit Assignee: dmalcolm at gcc dot gnu.org Reporter: m...@nieper-wisskirchen.de Target Milestone: --- Created attachment 52812 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52812&action=edit libgccjit reproducer file Compiling and running the attached libgccjit reproducer file produces a null pointer access in GCC's tree-optimization path. The error goes away if I comment out the call to gcc_jit_block_add_assignment on line 1181 or if I replace the pointer to the function there ("address_of_program") with a null pointer in the form of gcc_jit_context_new_rvalue_from_ptr (ctxt_0x6fe3ff0, ptr_to_union_value__struct_processorunion_value_, NULL). The error also goes away if I replace both occurrences of "-O3" in reproducer.c with "-O1" or lower. $ gcc -lgccjit reproducer.c && valgrind ./a.out ==979255== Memcheck, a memory error detector ==979255== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==979255== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info ==979255== Command: ./a.out ==979255== ==979255== Invalid read of size 8 ==979255==at 0x5D85753: operator_minus::op1_range(irange&, tree_node*, irange const&, irange const&, tree_code) const (range-op.cc:1460) ==979255==by 0x5CAAC75: gori_compute::compute_operand1_range(irange&, gimple*, irange const&, tree_node*, fur_source&) (gimple-range-gori.cc:1024) ==979255==by 0x5CAACD9: gori_compute::compute_operand1_range(irange&, gimple*, irange const&, tree_node*, fur_source&) (gimple-range-gori.cc:1077) ==979255==by 0x5CAC775: gori_compute::outgoing_edge_range_p(irange&, edge_def*, tree_node*, range_query&) (gimple-range-gori.cc:1271) ==979255==by 0x5CA0FDC: ranger_cache::range_on_edge(irange&, edge_def*, tree_node*) [clone .part.0] (gimple-range-cache.cc:1083) ==979255==by 0x5C9DFE1: gimple_ranger::range_on_edge(irange&, edge_def*, tree_node*) (gimple-range.cc:245) ==979255==by 0x52DB39E: range_query::value_on_edge(edge_def*, tree_node*) (value-query.cc:107) ==979255==by 0x52BDDE7: rvrp_folder::value_on_edge(edge_def*, tree_node*) (tree-vrp.cc:4281) ==979255==by 0x51D419C: substitute_and_fold_engine::propagate_into_phi_args(basic_block_def*) (tree-ssa-propagate.cc:742) ==979255==by 0x51D4CD7: substitute_and_fold_dom_walker::before_dom_children(basic_block_def*) (tree-ssa-propagate.cc:942) ==979255==by 0x5C70125: dom_walker::walk(basic_block_def*) (domwalk.cc:309) ==979255==by 0x51D3B6E: substitute_and_fold_engine::substitute_and_fold(basic_block_def*) (tree-ssa-propagate.cc:987) ==979255== Address 0x0 is not stack'd, malloc'd or (recently) free'd ==979255== ==979255== ==979255== Process terminating with default action of signal 11 (SIGSEGV) ==979255== Access not within mapped region at address 0x0 ==979255==at 0x5D85753: operator_minus::op1_range(irange&, tree_node*, irange const&, irange const&, tree_code) const (range-op.cc:1460) ==979255==by 0x5CAAC75: gori_compute::compute_operand1_range(irange&, gimple*, irange const&, tree_node*, fur_source&) (gimple-range-gori.cc:1024) ==979255==by 0x5CAACD9: gori_compute::compute_operand1_range(irange&, gimple*, irange const&, tree_node*, fur_source&) (gimple-range-gori.cc:1077) ==979255==by 0x5CAC775: gori_compute::outgoing_edge_range_p(irange&, edge_def*, tree_node*, range_query&) (gimple-range-gori.cc:1271) ==979255==by 0x5CA0FDC: ranger_cache::range_on_edge(irange&, edge_def*, tree_node*) [clone .part.0] (gimple-range-cache.cc:1083) ==979255==by 0x5C9DFE1: gimple_ranger::range_on_edge(irange&, edge_def*, tree_node*) (gimple-range.cc:245) ==979255==by 0x52DB39E: range_query::value_on_edge(edge_def*, tree_node*) (value-query.cc:107) ==979255==by 0x52BDDE7: rvrp_folder::value_on_edge(edge_def*, tree_node*) (tree-vrp.cc:4281) ==979255==by 0x51D419C: substitute_and_fold_engine::propagate_into_phi_args(basic_block_def*) (tree-ssa-propagate.cc:742) ==979255==by 0x51D4CD7: substitute_and_fold_dom_walker::before_dom_children(basic_block_def*) (tree-ssa-propagate.cc:942) ==979255==by 0x5C70125: dom_walker::walk(basic_block_def*) (domwalk.cc:309) ==979255==by 0x51D3B6E: substitute_and_fold_engine::substitute_and_fold(basic_block_def*) (tree-ssa-propagate.cc:987) ==979255== If you believe this happened as a result of a stack ==979255== overflow in your program's main thread (unlikely but ==979255== possible), you can try to increase the size of the ==979255== main thread stack using the --main-stacksize= flag. ==979255== The main thread stack size used in this run was 67108864. ==979255== ==979255== HEAP SUMM
[Bug jit/105286] New: Struct initializers do not work with function pointers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105286 Bug ID: 105286 Summary: Struct initializers do not work with function pointers Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: jit Assignee: dmalcolm at gcc dot gnu.org Reporter: m...@nieper-wisskirchen.de Target Milestone: --- Created attachment 52815 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52815&action=edit Sample C source demonstrating the issue Please consider the attached C file repro.c. $ gcc -lgccjit repro.c && ./a.out libgccjit.so: error: gcc_jit_context_new_struct_constructor: value and field not the same unqualified type, at index 0 (struct struct.func: void (*) ())(value type: void (*) ()) libgccjit.so: error: gcc_jit_global_set_initializer_rvalue: NULL init_rvalue gcc_jit_result_release: NULL result The second error is caused by the first, which is the one I am reporting here.
[Bug jit/105279] Using libgccjit produces a null pointer access in GCC's tree-optimization code
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105279 --- Comment #1 from Marc Nieper-Wißkirchen --- The internal compiler error also seems to go away if I remove the pointer subtraction around line 1833 in reproducer.c. Maybe this is the real problem because I am not subtracting pointers the way I should do in libgccjit (but still, it shouldn't crash). But if this is not the way to do it, is there another way to achieve pointer subtraction (besides bitcasting the pointers to integers)?
[Bug jit/105296] New: libgccjit crashes when creating a struct constructor for an aligned struct type
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105296 Bug ID: 105296 Summary: libgccjit crashes when creating a struct constructor for an aligned struct type Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: jit Assignee: dmalcolm at gcc dot gnu.org Reporter: m...@nieper-wisskirchen.de Target Milestone: --- Consider the following example program: #include int main (void) { gcc_jit_context *ctxt = gcc_jit_context_acquire (); gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); gcc_jit_field *field = gcc_jit_context_new_field (ctxt, NULL, int_type, "int"); gcc_jit_struct *struct_ = gcc_jit_context_new_struct_type (ctxt, NULL, "struct", 1, (gcc_jit_field *[]) {field}); gcc_jit_type *struct_type = gcc_jit_struct_as_type (struct_); gcc_jit_type *aligned_struct_type = gcc_jit_type_get_aligned (struct_type, 16); gcc_jit_lvalue *global = gcc_jit_context_new_global (ctxt, NULL, GCC_JIT_GLOBAL_EXPORTED, aligned_struct_type, "global"); gcc_jit_rvalue *val = gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 42); gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor (ctxt, NULL, aligned_struct_type, 1, (gcc_jit_field *[]) {field}, (gcc_jit_rvalue *[]) {val}); gcc_jit_global_set_initializer_rvalue (global, ctor); gcc_jit_result *res = gcc_jit_context_compile (ctxt); gcc_jit_context_release (ctxt); gcc_jit_result_release (res); } On my system, I get: $ gcc -lgccjit struct.c && valgrind ./a.out ==1022902== Memcheck, a memory error detector ==1022902== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==1022902== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info ==1022902== Command: ./a.out ==1022902== ==1022902== Invalid read of size 8 ==1022902==at 0x4B7F3CF: get_fields (jit-recording.h:968) ==1022902==by 0x4B7F3CF: gcc_jit_context_new_struct_constructor (libgccjit.cc:1436) ==1022902==by 0x4012F7: main (in /home/mnieper/tmp/a.out) ==1022902== Address 0x6fbbfc8 is 0 bytes after a block of size 56 alloc'd ==1022902==at 0x4843839: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==1022902==by 0x5EC26AB: operator new(unsigned long) (new_op.cc:50) ==1022902==by 0x4B90F47: gcc::jit::recording::type::get_aligned(unsigned long) (jit-recording.cc:2295) ==1022902==by 0x4B853FE: gcc_jit_type_get_aligned (libgccjit.cc:3950) ==1022902==by 0x401278: main (in /home/mnieper/tmp/a.out) ==1022902== ==1022902== Invalid read of size 8 ==1022902==at 0x4B7F3D3: length (vec.h:1473) ==1022902==by 0x4B7F3D3: length (jit-recording.h:1033) ==1022902==by 0x4B7F3D3: gcc_jit_context_new_struct_constructor (libgccjit.cc:1437) ==1022902==by 0x4012F7: main (in /home/mnieper/tmp/a.out) ==1022902== Address 0x28 is not stack'd, malloc'd or (recently) free'd ==1022902== ==1022902== ==1022902== Process terminating with default action of signal 11 (SIGSEGV) ==1022902== Access not within mapped region at address 0x28 ==1022902==at 0x4B7F3D3: length (vec.h:1473) ==1022902==by 0x4B7F3D3: length (jit-recording.h:1033) ==1022902==by 0x4B7F3D3: gcc_jit_context_new_struct_constructor (libgccjit.cc:1437) ==1022902==by 0x4012F7: main (in /home/mnieper/tmp/a.out) ==1022902== If you believe this happened as a result of a stack ==1022902== overflow in your program's main thread (unlikely but ==1022902== possible), you can try to increase the size of the ==1022902== main thread stack using the --main-stacksize= flag. ==1022902== The main thread stack size used in this run was 8388608. ==1022902== ==1022902== HEAP SUMMARY: ==1022902== in use at exit: 79,354 bytes in 46 blocks ==1022902== total heap usage: 48 allocs, 2 frees, 79,466 bytes allocated ==1022902== ==1022902== LEAK SUMMARY: ==1022902==definitely lost: 0 bytes in 0 blocks ==1022902==indirectly lost: 0 bytes in 0 blocks ==1022902== possibly lost: 0 bytes in 0 blocks ==1022902==still reachable: 79,354 bytes in 46 blocks ==1022902== suppressed: 0 bytes in 0 blocks ==1022902== Rerun with --leak-check=full to see details of leaked memory ==1022902== ==1022902== For lists of detected and suppressed errors, rerun with: -s ==1022902== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) Speicherzugriffsfehler (Speicherabzug geschrieben)
[Bug tree-optimization/86465] [9/10/11/12 Regression] C++17 triggers: ‘’ may be used uninitialized in this function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86465 --- Comment #17 from Marc Nieper-Wißkirchen --- Does a viable workaround exist that doesn't amount to disabling the warning option altogether? In my case, the actual warning is triggered inside the standard library, which is used by my code that uses std::optional. Thanks.
[Bug tree-optimization/103989] New: [12 regression] std::optional and bogus -Wmaybe-unitialized at -Og
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103989 Bug ID: 103989 Summary: [12 regression] std::optional and bogus -Wmaybe-unitialized at -Og Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: m...@nieper-wisskirchen.de Target Milestone: --- With the trunk version of GCC compiling the following program with -std=c++17 -Og -Wall -Werror gives a bogus maybe-uninitialized error (in the standard library component for the shared pointer): #include #include struct A { A (int a) : a {a} {} const std::shared_ptr x; int a; }; class B { public: B (const std::optional & a) : a {a} { } public: const std::optional a; }; int main () { B b {std::nullopt}; } Compiling it with -std=c++17 -O1 -Wall -Werror doesn't produce the error. As the code compiles find at -Og and -O1 with GCC 11.2, this is a regression. The error triggering is brittle. It goes away if the dummy member variable a in class A is removed, for example. For experimentation, the test case can be found here: https://godbolt.org/z/arGKT7d5n.
[Bug tree-optimization/86465] [9/10/11/12 Regression] C++17 triggers: ‘’ may be used uninitialized in this function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86465 Marc Nieper-Wißkirchen changed: What|Removed |Added CC||m...@nieper-wisskirchen.de --- Comment #18 from Marc Nieper-Wißkirchen --- Does a viable workaround exist that doesn't amount to disabling the warning option altogether? In my case, the actual warning is triggered inside the standard library, which is used by my code that uses std::optional. Thanks.
[Bug tree-optimization/104574] New: GCC misses basic optimization for restricted pointers
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104574 Bug ID: 104574 Summary: GCC misses basic optimization for restricted pointers Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: m...@nieper-wisskirchen.de Target Milestone: --- The following TU void g (void); int f (int *restrict p) { p[0] = 7; g (); return p[0]; } is compiled by GCC at -O3 to f: pushq %rbx movq%rdi, %rbx movl$7, (%rdi) callg movl(%rbx), %eax popq%rbx ret Obviously, GCC seems to think that g may modify the data reachable through p. However, if g did that it would cause undefined behavior anyway. So GCC misses a simple optimization opportunity here; it doesn't have to reload the memory contents after the call to g; in fact, the function will always return 7. For comparison, Clang compiles the TU to f: pushq %rax movl$7, (%rdi) callq g movl$7, %eax popq%rcx retq
[Bug tree-optimization/89479] __restrict on a pointer ignored when disambiguating against a call
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89479 --- Comment #11 from Marc Nieper-Wißkirchen --- (In reply to Richard Biener from comment #1 of bug 94416) > I think there's a duplicate somewhere. We currently cannot encode "restrict" > into the "accesses" implied by a call. > > Note there's slight complication when g (b) eventually recurses into 'f' > passing this 'b' as 'a'. Recursion makes the interpretation of the > lexically defined restrict concept a bit weird. > > So I think this bug can be closed as duplicate of the "restrict and calls" > bug. > > *** This bug has been marked as a duplicate of bug 89479 *** What do you mean by that the restrict concept is lexically defined? If I read the standard correctly, restrict makes an assumption about the dynamic extent of an executed block. This seems obvious from section 6.7.3.1 (of ISO C18) which speaks of the block of main in paragraph 2 and the lifetime of objects in paragraph 5.
[Bug analyzer/103546] New: Analyzer reports null dereference in flex scanners
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103546 Bug ID: 103546 Summary: Analyzer reports null dereference in flex scanners Product: gcc Version: 11.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: analyzer Assignee: dmalcolm at gcc dot gnu.org Reporter: m...@nieper-wisskirchen.de Target Milestone: --- I am trying to compile a flex-generated lexical scanner with the analyzer enabled. However, the analyzer reports a NULL dereference in the flex-generated file. Is this really a bug in Flex? It looks like a false positive to me. This is the MWE: $ flex --version flex 2.6.4 $ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/11/lto-wrapper OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa OFFLOAD_TARGET_DEFAULT=1 Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 11.2.0-7ubuntu2' --with-bugurl=file:///usr/share/doc/gcc-11/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-11 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-11-ZPT0kp/gcc-11-11.2.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-11-ZPT0kp/gcc-11-11.2.0/debian/tmp-gcn/usr --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2 Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 11.2.0 (Ubuntu 11.2.0-7ubuntu2) $ cat scan.l %% $ flex scan.l $ gcc -fanalyzer -Werror -c lex.yy.c In function ‘yy_init_buffer’: lex.yy.c:1290:26: error: dereference of NULL ‘b’ [CWE-476] [-Werror=analyzer-null-dereference]