Commit 4155777d by Nathan Sidwell Committed by Nathan Sidwell

[C++ PATCH] refactor duplicate_decls

https://gcc.gnu.org/ml/gcc-patches/2018-11/msg00085.html
	gcc/cp/
	* decl.c (duplicate_decls): Refactor checks.
	gcc/testsuite/
	* g++.dg/lookup/crash6.C: Adjust error
	* g++.dg/parse/crash38.C: Likewise.

From-SVN: r265744
parent 97f5962a
2018-11-02 Nathan Sidwell <nathan@acm.org>
* decl.c (duplicate_decls): Refactor checks.
2018-11-01 Marek Polacek <polacek@redhat.com> 2018-11-01 Marek Polacek <polacek@redhat.com>
Implement P0846R0, ADL and function templates. Implement P0846R0, ADL and function templates.
......
...@@ -1370,47 +1370,6 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) ...@@ -1370,47 +1370,6 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
|| TREE_TYPE (olddecl) == error_mark_node) || TREE_TYPE (olddecl) == error_mark_node)
return error_mark_node; return error_mark_node;
if (DECL_NAME (newdecl)
&& DECL_NAME (olddecl)
&& UDLIT_OPER_P (DECL_NAME (newdecl))
&& UDLIT_OPER_P (DECL_NAME (olddecl)))
{
if (TREE_CODE (newdecl) == TEMPLATE_DECL
&& TREE_CODE (olddecl) != TEMPLATE_DECL
&& check_raw_literal_operator (olddecl))
error_at (newdecl_loc,
"literal operator template %qD conflicts with"
" raw literal operator %qD", newdecl, olddecl);
else if (TREE_CODE (newdecl) != TEMPLATE_DECL
&& TREE_CODE (olddecl) == TEMPLATE_DECL
&& check_raw_literal_operator (newdecl))
error_at (newdecl_loc,
"raw literal operator %qD conflicts with"
" literal operator template %qD", newdecl, olddecl);
}
/* True to merge attributes between the declarations, false to
set OLDDECL's attributes to those of NEWDECL (for template
explicit specializations that specify their own attributes
independent of those specified for the primary template). */
const bool merge_attr = (TREE_CODE (newdecl) != FUNCTION_DECL
|| !DECL_TEMPLATE_SPECIALIZATION (newdecl)
|| DECL_TEMPLATE_SPECIALIZATION (olddecl));
if (DECL_P (olddecl)
&& TREE_CODE (newdecl) == FUNCTION_DECL
&& TREE_CODE (olddecl) == FUNCTION_DECL
&& merge_attr
&& diagnose_mismatched_attributes (olddecl, newdecl))
{
if (DECL_INITIAL (olddecl))
inform (olddecl_loc,
"previous definition of %qD was here", olddecl);
else
inform (olddecl_loc,
"previous declaration of %qD was here", olddecl);
}
/* Check for redeclaration and other discrepancies. */ /* Check for redeclaration and other discrepancies. */
if (TREE_CODE (olddecl) == FUNCTION_DECL if (TREE_CODE (olddecl) == FUNCTION_DECL
&& DECL_ARTIFICIAL (olddecl)) && DECL_ARTIFICIAL (olddecl))
...@@ -1634,38 +1593,45 @@ next_arg:; ...@@ -1634,38 +1593,45 @@ next_arg:;
/* C++ Standard, 3.3, clause 4: /* C++ Standard, 3.3, clause 4:
"[Note: a namespace name or a class template name must be unique "[Note: a namespace name or a class template name must be unique
in its declarative region (7.3.2, clause 14). ]" */ in its declarative region (7.3.2, clause 14). ]" */
if (TREE_CODE (olddecl) != NAMESPACE_DECL if (TREE_CODE (olddecl) == NAMESPACE_DECL
&& TREE_CODE (newdecl) != NAMESPACE_DECL || TREE_CODE (newdecl) == NAMESPACE_DECL)
&& (TREE_CODE (olddecl) != TEMPLATE_DECL /* Namespace conflicts with not namespace. */;
|| TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) != TYPE_DECL) else if (DECL_TYPE_TEMPLATE_P (olddecl)
&& (TREE_CODE (newdecl) != TEMPLATE_DECL || DECL_TYPE_TEMPLATE_P (newdecl))
|| TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) != TYPE_DECL)) /* Class template conflicts. */;
{ else if ((TREE_CODE (newdecl) == FUNCTION_DECL
if ((TREE_CODE (olddecl) == TYPE_DECL && DECL_ARTIFICIAL (olddecl)
&& TREE_CODE (newdecl) != TYPE_DECL)
|| (TREE_CODE (newdecl) == TYPE_DECL && DECL_ARTIFICIAL (newdecl)
&& TREE_CODE (olddecl) != TYPE_DECL))
{
/* We do nothing special here, because C++ does such nasty
things with TYPE_DECLs. Instead, just let the TYPE_DECL
get shadowed, and know that if we need to find a TYPE_DECL
for a given name, we can look in the IDENTIFIER_TYPE_VALUE
slot of the identifier. */
return NULL_TREE;
}
if ((TREE_CODE (newdecl) == FUNCTION_DECL
&& DECL_FUNCTION_TEMPLATE_P (olddecl)) && DECL_FUNCTION_TEMPLATE_P (olddecl))
|| (TREE_CODE (olddecl) == FUNCTION_DECL || (TREE_CODE (olddecl) == FUNCTION_DECL
&& DECL_FUNCTION_TEMPLATE_P (newdecl))) && DECL_FUNCTION_TEMPLATE_P (newdecl)))
{
/* One is a function and the other is a template
function. */
if (!UDLIT_OPER_P (DECL_NAME (newdecl)))
return NULL_TREE; return NULL_TREE;
/* There can only be one! */
if (TREE_CODE (newdecl) == TEMPLATE_DECL
&& check_raw_literal_operator (olddecl))
error_at (newdecl_loc,
"literal operator %q#D conflicts with"
" raw literal operator", newdecl);
else if (check_raw_literal_operator (newdecl))
error_at (newdecl_loc,
"raw literal operator %q#D conflicts with"
" literal operator template", newdecl);
else
return NULL_TREE;
inform (olddecl_loc, "previous declaration %q#D", olddecl);
return error_mark_node;
} }
else if (DECL_IMPLICIT_TYPEDEF_P (olddecl)
|| DECL_IMPLICIT_TYPEDEF_P (newdecl))
/* One is an implicit typedef, that's ok. */
return NULL_TREE;
error ("%q#D redeclared as different kind of symbol", newdecl); error ("%q#D redeclared as different kind of entity", newdecl);
if (TREE_CODE (olddecl) == TREE_LIST) inform (olddecl_loc, "previous declaration %q#D", olddecl);
olddecl = TREE_VALUE (olddecl);
inform (olddecl_loc,
"previous declaration %q#D", olddecl);
return error_mark_node; return error_mark_node;
} }
...@@ -1700,8 +1666,8 @@ next_arg:; ...@@ -1700,8 +1666,8 @@ next_arg:;
return type. */ return type. */
&& same_type_p (TREE_TYPE (TREE_TYPE (newdecl)), && same_type_p (TREE_TYPE (TREE_TYPE (newdecl)),
TREE_TYPE (TREE_TYPE (olddecl))) TREE_TYPE (TREE_TYPE (olddecl)))
// Template functions can also be disambiguated by /* Template functions can also be disambiguated by
// constraints. constraints. */
&& equivalently_constrained (olddecl, newdecl)) && equivalently_constrained (olddecl, newdecl))
{ {
error_at (newdecl_loc, "ambiguating new declaration %q#D", error_at (newdecl_loc, "ambiguating new declaration %q#D",
...@@ -1938,16 +1904,30 @@ next_arg:; ...@@ -1938,16 +1904,30 @@ next_arg:;
|| DECL_IMPLICIT_TYPEDEF_P (newdecl))) || DECL_IMPLICIT_TYPEDEF_P (newdecl)))
return NULL_TREE; return NULL_TREE;
if (!validate_constexpr_redeclaration (olddecl, newdecl))
return error_mark_node;
/* We have committed to returning OLDDECL at this point. */
/* If new decl is `static' and an `extern' was seen previously, /* If new decl is `static' and an `extern' was seen previously,
warn about it. */ warn about it. */
warn_extern_redeclared_static (newdecl, olddecl); warn_extern_redeclared_static (newdecl, olddecl);
if (!validate_constexpr_redeclaration (olddecl, newdecl)) /* True to merge attributes between the declarations, false to
return error_mark_node; set OLDDECL's attributes to those of NEWDECL (for template
explicit specializations that specify their own attributes
independent of those specified for the primary template). */
const bool merge_attr = (TREE_CODE (newdecl) != FUNCTION_DECL
|| !DECL_TEMPLATE_SPECIALIZATION (newdecl)
|| DECL_TEMPLATE_SPECIALIZATION (olddecl));
/* We have committed to returning 1 at this point. */
if (TREE_CODE (newdecl) == FUNCTION_DECL) if (TREE_CODE (newdecl) == FUNCTION_DECL)
{ {
if (merge_attr && diagnose_mismatched_attributes (olddecl, newdecl))
inform (olddecl_loc, DECL_INITIAL (olddecl)
? G_("previous definition of %qD here")
: G_("previous declaration of %qD here"), olddecl);
/* Now that functions must hold information normally held /* Now that functions must hold information normally held
by field decls, there is extra work to do so that by field decls, there is extra work to do so that
declaration information does not get destroyed during declaration information does not get destroyed during
...@@ -2027,7 +2007,7 @@ next_arg:; ...@@ -2027,7 +2007,7 @@ next_arg:;
else else
DECL_ATTRIBUTES (olddecl) = DECL_ATTRIBUTES (newdecl); DECL_ATTRIBUTES (olddecl) = DECL_ATTRIBUTES (newdecl);
if (DECL_DECLARES_FUNCTION_P (olddecl) && DECL_DECLARES_FUNCTION_P (newdecl)) if (DECL_DECLARES_FUNCTION_P (olddecl))
{ {
olddecl_friend = DECL_FRIEND_P (olddecl); olddecl_friend = DECL_FRIEND_P (olddecl);
olddecl_hidden_friend = DECL_HIDDEN_FRIEND_P (olddecl); olddecl_hidden_friend = DECL_HIDDEN_FRIEND_P (olddecl);
......
2018-11-02 Nathan Sidwell <nathan@acm.org>
* g++.dg/lookup/crash6.C: Adjust error
* g++.dg/parse/crash38.C: Likewise.
2018-11-02 Andreas Schwab <schwab@linux-m68k.org> 2018-11-02 Andreas Schwab <schwab@linux-m68k.org>
* gcc.c-torture/execute/20010904-2.c: Fix last change. * gcc.c-torture/execute/20010904-2.c: Fix last change.
......
...@@ -5,4 +5,4 @@ ...@@ -5,4 +5,4 @@
// PR c++/18652: ICE redeclaring variable as template. // PR c++/18652: ICE redeclaring variable as template.
int A; // { dg-message "previous declaration" } int A; // { dg-message "previous declaration" }
template<int> struct A; // { dg-error "different kind of symbol" } template<int> struct A; // { dg-error "different kind of" }
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
/* This would not ICE. */ /* This would not ICE. */
namespace M { } /* { dg-message "previous declaration" } */ namespace M { } /* { dg-message "previous declaration" } */
struct M; /* { dg-error "redeclared as different kind of symbol" } */ struct M; /* { dg-error "redeclared as different kind of" } */
M *p; /* { dg-error "does not name a type" } */ M *p; /* { dg-error "does not name a type" } */
/* This would ICE when processing 'p'. */ /* This would ICE when processing 'p'. */
namespace N { } /* { dg-message "previous declaration" } */ namespace N { } /* { dg-message "previous declaration" } */
struct N; /* { dg-error "redeclared as different kind of symbol" } */ struct N; /* { dg-error "redeclared as different kind of" } */
struct N* p; /* { dg-error "redeclared as different kind of symbol|invalid type" } */ struct N* p; /* { dg-error "redeclared as different kind of" } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment