}
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) {
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>("A"), item<B>("B"), item<C>("C"), item<int>("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{});
+
}
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}}
+}