https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80794
Bug ID: 80794 Summary: constant objects can be assumed to be immutable Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- Modifying a const object is undefined (1.9, p4 and 3.3, p1.1 of C++17). Therefore, valid C++ programs can be relied on not to modify const objects or subobjects to improve the efficiency of accessing such objects. For example, in both function foo and bar in the test case below, GCC can assume that the value of the s.i member after the call to s.f() is the same as its value before the call, and eliminate the test for the inequality. This should also hold for C but I suspect C programs more commonly violate this constraint than C++ programs do. $ cat t.C && gcc -O2 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout t.C struct S { const int i; S (int x): i (x) { } void f () const; }; const S s (123); void foo () { int i = s.i; s.f (); int j = s.i; if (i != j) __builtin_abort (); } void bar (const S &s) { int i = s.i; s.f (); int j = s.i; if (i != j) __builtin_abort (); } ;; Function void foo() (_Z3foov, funcdef_no=3, decl_uid=2318, cgraph_uid=3, symbol_order=4) void foo() () { int j; int i; <bb 2> [100.00%]: i_2 = s.i; S::f (&s); j_4 = s.i; if (i_2 != j_4) goto <bb 3>; [0.04%] else goto <bb 4>; [99.96%] <bb 3> [0.04%]: __builtin_abort (); <bb 4> [99.96%]: return; } ;; Function void bar(const S&) (_Z3barRK1S, funcdef_no=4, decl_uid=2323, cgraph_uid=4, symbol_order=5) void bar(const S&) (const struct S & s) { int j; int i; <bb 2> [100.00%]: i_3 = s_2(D)->i; S::f (s_2(D)); j_5 = s_2(D)->i; if (i_3 != j_5) goto <bb 3>; [0.04%] else goto <bb 4>; [99.96%] <bb 3> [0.04%]: __builtin_abort (); <bb 4> [99.96%]: return; } ;; Function (static initializers for t.C) (_GLOBAL__sub_I__Z3foov, funcdef_no=6, decl_uid=2332, cgraph_uid=6, symbol_order=7) (executed once) (static initializers for t.C) () { <bb 2> [100.00%]: MEM[(struct &)&s] ={v} {CLOBBER}; s.i = 123; return; }