c++: Tweak tsubst_qualified_id location.

Retain the location when tsubstituting a qualified-id so that our
static_assert diagnostic can benefit.  Don't create useless location
wrappers for temporary variables.

gcc/ChangeLog:

	PR c++/97518
	* tree.c (maybe_wrap_with_location): Don't add a location
	wrapper around an artificial and ignored decl.

gcc/cp/ChangeLog:

	PR c++/97518
	* pt.c (tsubst_qualified_id): Use EXPR_LOCATION of the qualified-id.
	Use it to maybe_wrap_with_location the final expression.

gcc/testsuite/ChangeLog:

	PR c++/97518
	* g++.dg/diagnostic/static_assert3.C: New test.
This commit is contained in:
Marek Polacek 2020-11-10 16:39:19 -05:00
parent 2e8b368c3d
commit d6e5745a9a
3 changed files with 43 additions and 2 deletions

View File

@ -16214,7 +16214,7 @@ tsubst_qualified_id (tree qualified_id, tree args,
tree name;
bool is_template;
tree template_args;
location_t loc = UNKNOWN_LOCATION;
location_t loc = EXPR_LOCATION (qualified_id);
gcc_assert (TREE_CODE (qualified_id) == SCOPE_REF);
@ -16223,7 +16223,6 @@ tsubst_qualified_id (tree qualified_id, tree args,
if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
{
is_template = true;
loc = EXPR_LOCATION (name);
template_args = TREE_OPERAND (name, 1);
if (template_args)
template_args = tsubst_template_args (template_args, args,
@ -16351,6 +16350,8 @@ tsubst_qualified_id (tree qualified_id, tree args,
if (REF_PARENTHESIZED_P (qualified_id))
expr = force_paren_expr (expr);
expr = maybe_wrap_with_location (expr, loc);
return expr;
}

View File

@ -0,0 +1,36 @@
// PR c++/97518
// { dg-do compile { target c++17 } }
// { dg-options "-fdiagnostics-show-caret" }
template <typename T, typename U> struct is_same { static constexpr bool value = false; };
template <typename T> struct is_same<T, T> { static constexpr bool value = true; };
template <typename T, typename U>
void f(T, U)
{
static_assert(is_same<T, T>::value && is_same<T, U>::value); // { dg-error "56:static assertion failed" }
/* { dg-begin-multiline-output "" }
static_assert(is_same<T, T>::value && is_same<T, U>::value);
^~~~~
{ dg-end-multiline-output "" } */
// { dg-message ".is_same<int, double>::value. evaluates to false" "" { target *-*-* } .-5 }
static_assert(is_same<U, T>::value && is_same<U, U>::value); // { dg-error "32:static assertion failed" }
/* { dg-begin-multiline-output "" }
static_assert(is_same<U, T>::value && is_same<U, U>::value);
^~~~~
{ dg-end-multiline-output "" } */
// { dg-message ".is_same<double, int>::value. evaluates to false" "" { target *-*-* } .-5 }
static_assert(is_same<U, U>::value
&& is_same<U, T>::value // { dg-error "35:static assertion failed" }
&& is_same<T, T>::value);
/* { dg-begin-multiline-output "" }
&& is_same<U, T>::value
^~~~~
{ dg-end-multiline-output "" } */
// { dg-message ".is_same<double, int>::value. evaluates to false" "" { target *-*-* } .-6 }
}
void g()
{
f(0, 1.3);
}

View File

@ -15041,6 +15041,10 @@ maybe_wrap_with_location (tree expr, location_t loc)
if (EXCEPTIONAL_CLASS_P (expr))
return expr;
/* Compiler-generated temporary variables don't need a wrapper. */
if (DECL_P (expr) && DECL_ARTIFICIAL (expr) && DECL_IGNORED_P (expr))
return expr;
/* If any auto_suppress_location_wrappers are active, don't create
wrappers. */
if (suppress_location_wrappers > 0)