From 9be36ab27b874b404099650e0c29bc92f3c7662d Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Wed, 17 Oct 2012 23:52:07 +0000 Subject: [PATCH] DR1535: only potentially-evaluated typeid expressions are disallowed in constant expressions, not *any* typeid on a polymorphic class type. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166156 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/ExprConstant.cpp | 18 ++++++------------ test/CodeGenCXX/typeid-cxx11.cpp | 8 +++++--- test/SemaCXX/constant-expression-cxx11.cpp | 11 +++++++++++ 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 323a1746bf..6e0b5fca60 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -2886,19 +2886,13 @@ LValueExprEvaluator::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) { } bool LValueExprEvaluator::VisitCXXTypeidExpr(const CXXTypeidExpr *E) { - if (E->isTypeOperand()) + if (!E->isPotentiallyEvaluated()) return Success(E); - CXXRecordDecl *RD = E->getExprOperand()->getType()->getAsCXXRecordDecl(); - // FIXME: The standard says "a typeid expression whose operand is of a - // polymorphic class type" is not a constant expression, but it probably - // means "a typeid expression whose operand is potentially evaluated". - if (RD && RD->isPolymorphic()) { - Info.Diag(E, diag::note_constexpr_typeid_polymorphic) - << E->getExprOperand()->getType() - << E->getExprOperand()->getSourceRange(); - return false; - } - return Success(E); + + Info.Diag(E, diag::note_constexpr_typeid_polymorphic) + << E->getExprOperand()->getType() + << E->getExprOperand()->getSourceRange(); + return false; } bool LValueExprEvaluator::VisitCXXUuidofExpr(const CXXUuidofExpr *E) { diff --git a/test/CodeGenCXX/typeid-cxx11.cpp b/test/CodeGenCXX/typeid-cxx11.cpp index 940274e965..4e32d2dcb5 100644 --- a/test/CodeGenCXX/typeid-cxx11.cpp +++ b/test/CodeGenCXX/typeid-cxx11.cpp @@ -18,13 +18,15 @@ struct A { virtual ~A(); }; struct B : virtual A {}; struct C { int n; }; -// FIXME: check we produce a constant array for this, once we support IRGen of -// folded structs and arrays. +// CHECK: @_ZN5Test1L5itemsE = internal constant [4 x {{.*}}] [{{.*}} @_ZTIN5Test11AE {{.*}}, {{.*}}, {{.*}} @_ZN5Test19make_implINS_1AEEEPvv }, {{.*}} @_ZTIN5Test11BE {{.*}} @_ZN5Test19make_implINS_1BEEEPvv {{.*}} @_ZTIN5Test11CE {{.*}} @_ZN5Test19make_implINS_1CEEEPvv {{.*}} @_ZTIi {{.*}} @_ZN5Test19make_implIiEEPvv }] constexpr Item items[] = { item("A"), item("B"), item("C"), item("int") }; -// CHECK: @_ZN5Test11xE = constant %"class.std::type_info"* bitcast (i8** @_ZTIN5Test11AE to %"class.std::type_info"*), align 8 +// CHECK: @_ZN5Test11xE = constant %"class.std::type_info"* bitcast ({{.*}}* @_ZTIN5Test11AE to %"class.std::type_info"*), align 8 constexpr auto &x = items[0].ti; +// CHECK: @_ZN5Test11yE = constant %"class.std::type_info"* bitcast ({{.*}}* @_ZTIN5Test11BE to %"class.std::type_info"*), align 8 +constexpr auto &y = typeid(B{}); + } diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp index 065e396b15..583344c793 100644 --- a/test/SemaCXX/constant-expression-cxx11.cpp +++ b/test/SemaCXX/constant-expression-cxx11.cpp @@ -1408,3 +1408,14 @@ namespace Void { static_assert(get(arr, 0) == 4, ""); // expected-error{{not an integral constant expression}} \ // expected-note{{in call to 'get(arr, 0)'}} } + +namespace std { struct type_info; } + +namespace TypeId { + struct A { virtual ~A(); }; + A f(); + A &g(); + constexpr auto &x = typeid(f()); + constexpr auto &y = typeid(g()); // expected-error{{constant expression}} \ + // expected-note{{typeid applied to expression of polymorphic type 'TypeId::A' is not allowed in a constant expression}} +} -- 2.40.0