> We should be able to assume that a template instantiation or other COMDAT
> has non-zero address even if MAKE_DECL_ONE_ONLY for the target sets
> DECL_WEAK and we haven't yet decided to emit a definition in this
> translation unit.
> 
> Tested x86_64-pc-linux-gnu, OK for trunk?
> 
>       PR c++/92003
>       * symtab.c (symtab_node::nonzero_address): A DECL_COMDAT decl has
>       non-zero address even if weak and not yet defined.
OK, thanks!

Honza
> ---
>  gcc/symtab.c                                    | 10 +++++-----
>  gcc/testsuite/g++.dg/cpp0x/constexpr-static13.C | 17 +++++++++++++++++
>  2 files changed, 22 insertions(+), 5 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-static13.C
> 
> diff --git a/gcc/symtab.c b/gcc/symtab.c
> index eae891ab211..a879c095a1a 100644
> --- a/gcc/symtab.c
> +++ b/gcc/symtab.c
> @@ -2058,22 +2058,22 @@ symtab_node::nonzero_address ()
>       bind to NULL. This is on by default on embedded targets only.
>  
>       Otherwise all non-WEAK symbols must be defined and thus non-NULL or
> -     linking fails.  Important case of WEAK we want to do well are comdats.
> -     Those are handled by later check for definition.
> +     linking fails.  Important case of WEAK we want to do well are comdats,
> +     which also must be defined somewhere.
>  
>       When parsing, beware the cases when WEAK attribute is added later.  */
> -  if (!DECL_WEAK (decl)
> +  if ((!DECL_WEAK (decl) || DECL_COMDAT (decl))
>        && flag_delete_null_pointer_checks)
>      {
>        refuse_visibility_changes = true;
>        return true;
>      }
>  
> -  /* If target is defined and either comdat or not extern, we know it will be
> +  /* If target is defined and not extern, we know it will be
>       output and thus it will bind to non-NULL.
>       Play safe for flag_delete_null_pointer_checks where weak definition may
>       be re-defined by NULL.  */
> -  if (definition && (!DECL_EXTERNAL (decl) || DECL_COMDAT (decl))
> +  if (definition && !DECL_EXTERNAL (decl)
>        && (flag_delete_null_pointer_checks || !DECL_WEAK (decl)))
>      {
>        if (!DECL_WEAK (decl))
> diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-static13.C 
> b/gcc/testsuite/g++.dg/cpp0x/constexpr-static13.C
> new file mode 100644
> index 00000000000..644f9f7f893
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-static13.C
> @@ -0,0 +1,17 @@
> +// PR c++/92003
> +// { dg-do compile { target c++11 } }
> +// { dg-prune-output "narrowing conversion" }
> +
> +constexpr char const* get_c_str() { return "abc"; }
> +constexpr bool use_get_c_str_in_constexpr_context{get_c_str()}; // works
> +
> +template <char... Cs>
> +struct string {
> +  static constexpr char const* c_str() { return c; }
> +
> + private:
> +  static constexpr char c[]{Cs..., '\0'};
> +};
> +
> +constexpr char const* cstr{string<'a', 'b', 'c'>::c_str()};
> +constexpr bool use_cstr_in_constexpr_context{cstr}; // doesn't work
> 
> base-commit: fa0c6e297b22d5883857d0db4a6a8be0967cb16f
> -- 
> 2.18.1
> 

Reply via email to