aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2020-11-10 16:39:19 -0500
committerMarek Polacek <polacek@redhat.com>2020-11-11 12:36:52 -0500
commitd6e5745a9a88314e27f387b2277299076862af67 (patch)
tree71ce4bec306b8303730e6a6c4257c3109ed045b2 /gcc
parent2e8b368c3d33fd8ddafdd37f8e1b2ba45d1a122e (diff)
downloadgcc-d6e5745a9a88314e27f387b2277299076862af67.zip
gcc-d6e5745a9a88314e27f387b2277299076862af67.tar.gz
gcc-d6e5745a9a88314e27f387b2277299076862af67.tar.bz2
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/pt.c5
-rw-r--r--gcc/testsuite/g++.dg/diagnostic/static_assert3.C36
-rw-r--r--gcc/tree.c4
3 files changed, 43 insertions, 2 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 6ba114c..c592461 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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;
}
diff --git a/gcc/testsuite/g++.dg/diagnostic/static_assert3.C b/gcc/testsuite/g++.dg/diagnostic/static_assert3.C
new file mode 100644
index 0000000..5d36388
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/static_assert3.C
@@ -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);
+}
diff --git a/gcc/tree.c b/gcc/tree.c
index 1d4a1da..1ad4ad5 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -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)