https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68699

            Bug ID: 68699
           Summary: Wrong location_t due to template instance
                    canonicalization when setting location_t values on
                    expressions
           Product: gcc
           Version: 6.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: dmalcolm at gcc dot gnu.org
  Target Milestone: ---

As discussed in the thread starting at
  https://gcc.gnu.org/ml/gcc-patches/2015-12/msg00449.html

Testcase g++.dg/template/ref3.C:

     1  // PR c++/28341
     2
     3  template<const int&> struct A {};
     4
     5  template<typename T> struct B
     6  {
     7    A<(T)0> b; // { dg-error "constant|not a valid" }
     8    A<T(0)> a; // { dg-error "constant|not a valid" }
     9  };
    10
    11  B<const int&> b;

With c++98, with trunk (e.g. r231208), we get this output

g++.dg/template/ref3.C: In instantiation of 'struct B<const int&>':
g++.dg/template/ref3.C:11:15:   required from here
g++.dg/template/ref3.C:7:11: error: a cast to a type other than an integral or
enumeration type cannot appear in a constant-expression
g++.dg/template/ref3.C:8:11: error: a cast to a type other than an integral or
enumeration type cannot appear in a constant-expression

(locations 7:11 and 8:11 are at the closing semicolon for fields b and a)

Upon updating the C++ FE to set up location_t values for expressions,
in particular the bogus cast expressions (T)0 and T(0):

   A<(T)0> b;
     ^~~~

and:

   A<T(0)> a;
     ^~~~

both instantiations are reported at line 7, rather than at lines 7 and 8:

g++.dg/template/ref3.C:7:5: error: a cast to a type other than an integral or
enumeration type cannot appear in a constant-expression
g++.dg/template/ref3.C:7:5: error: a cast to a type other than an integral or
enumeration type cannot appear in a constant-expression

This is because both instantiations are using a single RECORD_TYPE
for the type A<(T)(0)>.  We get a hit the 2nd time through this code
in pt.c:

8282          entry = type_specializations->find_with_hash (&elt, hash);

Hence when issuing both errors it uses the TREE_VEC of args for the
first one, rather than the most pertinent location.

Reply via email to