https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103827
--- Comment #16 from Jan Hubicka <hubicka at ucw dot cz> --- > > Note that this is the same for non-parameter local variables > > Just want to emphasize this point: this property is in no way specific to > parameters, it applies to any object created as const. If someone wants to > use > a pointer that previously pointed to a const object to refer to a new const > object at the same address, they need to use std::launder to make the compiler > forget about the old object. We are not too good on using const on automatic variables and static ones with constructors since they become effectively const only when they are constructed and it is not clear when this is done. For parameters this is easier: they are const for whole duration of the function. I am testing the following which simply re-uses what we do for readonly fnspec. It optimizes away the "optimize me away2" string from the testcase... gcc/ChangeLog: * attr-fnspec.h (attr_fnspec constructor): Allow NULL_TREE. * tree-into-ssa.cc (pass_build_ssa::execute): Also set SSA_NAME_POINTS_TO_READONLY_MEMORY for parameters passed by invisible reference and declared const. diff --git a/gcc/attr-fnspec.h b/gcc/attr-fnspec.h index aef4701e6d1..76053d88b09 100644 --- a/gcc/attr-fnspec.h +++ b/gcc/attr-fnspec.h @@ -93,8 +97,8 @@ public: verify (); } attr_fnspec (const_tree identifier) - : str (TREE_STRING_POINTER (identifier)), - len (TREE_STRING_LENGTH (identifier)) + : str (identifier ? TREE_STRING_POINTER (identifier) : NULL), + len (identifier ? TREE_STRING_LENGTH (identifier) : 0) { if (flag_checking) verify (); diff --git a/gcc/tree-into-ssa.cc b/gcc/tree-into-ssa.cc index df1fb186962..0267a86f1cc 100644 --- a/gcc/tree-into-ssa.cc +++ b/gcc/tree-into-ssa.cc @@ -2555,25 +2556,23 @@ pass_build_ssa::execute (function *fun) SET_SSA_NAME_VAR_OR_IDENTIFIER (name, DECL_NAME (decl)); } - /* Initialize SSA_NAME_POINTS_TO_READONLY_MEMORY. */ + /* Initialize SSA_NAME_POINTS_TO_READONLY_MEMORY using fnspec or for + values passed by invisible reference declared const. */ tree fnspec_tree = lookup_attribute ("fn spec", TYPE_ATTRIBUTES (TREE_TYPE (fun->decl))); - if (fnspec_tree) - { - attr_fnspec fnspec (TREE_VALUE (TREE_VALUE (fnspec_tree))); - unsigned i = 0; - for (tree arg = DECL_ARGUMENTS (cfun->decl); - arg; arg = DECL_CHAIN (arg), ++i) + attr_fnspec fnspec (fnspec_tree ? TREE_VALUE (TREE_VALUE (fnspec_tree)) : NULL); + i = 0; + for (tree arg = DECL_ARGUMENTS (cfun->decl); + arg; arg = DECL_CHAIN (arg), ++i) + { + if ((fnspec.arg_specified_p (i) && fnspec.arg_readonly_p (i)) + || (DECL_BY_REFERENCE (arg) + && TYPE_READONLY (TREE_TYPE (TREE_TYPE (arg))))) { - if (!fnspec.arg_specified_p (i)) - break; - if (fnspec.arg_readonly_p (i)) - { - tree name = ssa_default_def (fun, arg); - if (name) - SSA_NAME_POINTS_TO_READONLY_MEMORY (name) = 1; - } + tree name = ssa_default_def (fun, arg); + if (name) + SSA_NAME_POINTS_TO_READONLY_MEMORY (name) = 1; } }