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

            Bug ID: 79629
           Summary: ICE on invalid code in tsubst_copy, at cp/pt.c:14477
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Keywords: ice-on-invalid-code
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: marxin at gcc dot gnu.org
                CC: jason at gcc dot gnu.org
  Target Milestone: ---

We ICE on a LLVM test-case:

$ cat
/home/marxin/BIG/Programming/llvm-project/llvm/tools/clang/test/SemaCXX/enum-unscoped-nonexistent.cpp

// RUN: %clang_cc1 -std=c++11 -verify %s

struct Base {
  static const int a = 1;
};
template<typename T> struct S : Base {
  enum E : int;
  constexpr int f() const;
  constexpr int g() const;
  void h();
};
template<> enum S<char>::E : int {}; // expected-note {{enum 'S<char>::E' was
explicitly specialized here}}
template<> enum S<short>::E : int { b = 2 };
template<> enum S<int>::E : int { a = 4 };
template<typename T> enum S<T>::E : int { b = 8 };

// The unqualified-id here names a member of the non-dependent base class Base
// and not the injected enumerator name 'a' from the specialization.
template<typename T> constexpr int S<T>::f() const { return a; }
static_assert(S<char>().f() == 1, "");
static_assert(S<int>().f() == 1, "");

// The unqualified-id here names a member of the current instantiation, which
// bizarrely might not exist in some instantiations.
template<typename T> constexpr int S<T>::g() const { return b; } //
expected-error {{enumerator 'b' does not exist in instantiation of 'S<char>'}}
static_assert(S<char>().g() == 1, ""); // expected-note {{here}} expected-error
{{not an integral constant expression}}
static_assert(S<short>().g() == 2, "");
static_assert(S<long>().g() == 8, "");

// 'b' is type-dependent, so these assertions should not fire before 'h' is
// instantiated.
template<typename T> void S<T>::h() {
  char c[S<T>::b];
  static_assert(b != 8, "");
  static_assert(sizeof(c) != 8, "");
}
void f() {
  S<short>().h(); // ok, b == 2
}

$ g++
/home/marxin/BIG/Programming/llvm-project/llvm/tools/clang/test/SemaCXX/enum-unscoped-nonexistent.cpp
/home/marxin/BIG/Programming/llvm-project/llvm/tools/clang/test/SemaCXX/enum-unscoped-nonexistent.cpp:
In instantiation of ‘constexpr int S<T>::g() const [with T = char]’:
/home/marxin/BIG/Programming/llvm-project/llvm/tools/clang/test/SemaCXX/enum-unscoped-nonexistent.cpp:26:26:
  required from here
/home/marxin/BIG/Programming/llvm-project/llvm/tools/clang/test/SemaCXX/enum-unscoped-nonexistent.cpp:25:61:
internal compiler error: in tsubst_copy, at cp/pt.c:14477
 template<typename T> constexpr int S<T>::g() const { return b; } //
expected-error {{enumerator 'b' does not exist in instantiation of 'S<char>'}}
                                                             ^
0x69b29c tsubst_copy
        ../../gcc/cp/pt.c:14477
0x69d128 tsubst_copy_and_build(tree_node*, tree_node*, int, tree_node*, bool,
bool)
        ../../gcc/cp/pt.c:17872
0x698d68 tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
        ../../gcc/cp/pt.c:16419
0x698bf6 tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
        ../../gcc/cp/pt.c:15680
0x698b83 tsubst_expr(tree_node*, tree_node*, int, tree_node*, bool)
        ../../gcc/cp/pt.c:15896
0x697267 instantiate_decl(tree_node*, bool, bool)
        ../../gcc/cp/pt.c:22840
0x78fc1d cxx_eval_call_expression
        ../../gcc/cp/constexpr.c:1493
0x791527 cxx_eval_constant_expression
        ../../gcc/cp/constexpr.c:3971
0x79490f cxx_eval_outermost_constant_expr
        ../../gcc/cp/constexpr.c:4613
0x796586 maybe_constant_value(tree_node*, tree_node*)
        ../../gcc/cp/constexpr.c:4828
0x782321 cp_fully_fold(tree_node*)
        ../../gcc/cp/cp-gimplify.c:1963
0x71b017 cp_build_binary_op(unsigned int, tree_code, tree_node*, tree_node*,
int)
        ../../gcc/cp/typeck.c:5243
0x661726 build_new_op_1
        ../../gcc/cp/call.c:5982
0x66225e build_new_op(unsigned int, tree_code, int, tree_node*, tree_node*,
tree_node*, tree_node**, int)
        ../../gcc/cp/call.c:6027
0x713192 build_x_binary_op(unsigned int, tree_code, tree_node*, tree_code,
tree_node*, tree_code, tree_node**, int)
        ../../gcc/cp/typeck.c:3930
0x6f6688 cp_parser_binary_expression
        ../../gcc/cp/parser.c:9060
0x6f6be0 cp_parser_assignment_expression
        ../../gcc/cp/parser.c:9190
0x6f6fc7 cp_parser_constant_expression
        ../../gcc/cp/parser.c:9460
0x6f70f8 cp_parser_static_assert
        ../../gcc/cp/parser.c:13607
0x706e98 cp_parser_block_declaration
        ../../gcc/cp/parser.c:12617

Reply via email to