I did some digging before reverting. The bots your patch is failing on are 32-bit CPUs. It looks like your static_assert is assuming 8-byte aligned pointers, so it always fails on the 32-bit builders.
-Chris > On May 16, 2019, at 10:14 PM, Chris Bieneman <chris.biene...@me.com> wrote: > > Sorry to do this, but I'm also reverting r360977, because it seems to be on > top of this one. > > -Chris > >> On May 16, 2019, at 9:58 PM, Chris Bieneman via cfe-commits >> <cfe-commits@lists.llvm.org> wrote: >> >> Hey Richard, >> >> This change is tripping up a bunch of the bots: >> >> http://lab.llvm.org:8011/builders/clang-cmake-armv8-lld/builds/1397 >> >> I'm going to revert it so that we don't leave the bots broken overnight. >> >> -Chris >> >>> On May 16, 2019, at 6:46 PM, Richard Smith via cfe-commits >>> <cfe-commits@lists.llvm.org> wrote: >>> >>> Author: rsmith >>> Date: Thu May 16 18:46:05 2019 >>> New Revision: 360974 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=360974&view=rev >>> Log: >>> Refactor constant evaluation of typeid(T) to track a symbolic type_info >>> object rather than tracking the originating expression. >>> >>> This is groundwork for supporting polymorphic typeid expressions. (Note >>> that this somewhat regresses our support for DR1968, but it turns out >>> that that never actually worked anyway, at least in non-trivial cases.) >>> >>> Modified: >>> cfe/trunk/include/clang/AST/APValue.h >>> cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td >>> cfe/trunk/lib/AST/APValue.cpp >>> cfe/trunk/lib/AST/ExprConstant.cpp >>> cfe/trunk/lib/CodeGen/CGExprConstant.cpp >>> cfe/trunk/lib/Sema/SemaTemplate.cpp >>> cfe/trunk/test/CXX/drs/dr19xx.cpp >>> cfe/trunk/test/Parser/MicrosoftExtensions.cpp >>> cfe/trunk/test/SemaCXX/builtin-constant-p.cpp >>> cfe/trunk/test/SemaCXX/typeid.cpp >>> cfe/trunk/www/cxx_dr_status.html >>> >>> Modified: cfe/trunk/include/clang/AST/APValue.h >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/APValue.h?rev=360974&r1=360973&r2=360974&view=diff >>> ============================================================================== >>> --- cfe/trunk/include/clang/AST/APValue.h (original) >>> +++ cfe/trunk/include/clang/AST/APValue.h Thu May 16 18:46:05 2019 >>> @@ -24,14 +24,52 @@ namespace clang { >>> class AddrLabelExpr; >>> class ASTContext; >>> class CharUnits; >>> + class CXXRecordDecl; >>> + class Decl; >>> class DiagnosticBuilder; >>> class Expr; >>> class FieldDecl; >>> - class Decl; >>> + struct PrintingPolicy; >>> + class Type; >>> class ValueDecl; >>> - class CXXRecordDecl; >>> - class QualType; >>> >>> +/// Symbolic representation of typeid(T) for some type T. >>> +class TypeInfoLValue { >>> + const Type *T; >>> + >>> +public: >>> + TypeInfoLValue() : T() {} >>> + explicit TypeInfoLValue(const Type *T); >>> + >>> + const Type *getType() const { return T; } >>> + explicit operator bool() const { return T; } >>> + >>> + void *getOpaqueValue() { return const_cast<Type*>(T); } >>> + static TypeInfoLValue getFromOpaqueValue(void *Value) { >>> + TypeInfoLValue V; >>> + V.T = reinterpret_cast<const Type*>(Value); >>> + return V; >>> + } >>> + >>> + void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy) const; >>> +}; >>> +} >>> + >>> +namespace llvm { >>> +template<> struct PointerLikeTypeTraits<clang::TypeInfoLValue> { >>> + static void *getAsVoidPointer(clang::TypeInfoLValue V) { >>> + return V.getOpaqueValue(); >>> + } >>> + static clang::TypeInfoLValue getFromVoidPointer(void *P) { >>> + return clang::TypeInfoLValue::getFromOpaqueValue(P); >>> + } >>> + // Validated by static_assert in APValue.cpp; hardcoded to avoid needing >>> + // to include Type.h. >>> + static constexpr int NumLowBitsAvailable = 3; >>> +}; >>> +} >>> + >>> +namespace clang { >>> /// APValue - This class implements a discriminated union of [uninitialized] >>> /// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset], >>> /// [Vector: N * APValue], [Array: N * APValue] >>> @@ -57,13 +95,18 @@ public: >>> >>> class LValueBase { >>> public: >>> - typedef llvm::PointerUnion<const ValueDecl *, const Expr *> PtrTy; >>> + typedef llvm::PointerUnion<const ValueDecl *, const Expr *, >>> TypeInfoLValue> >>> + PtrTy; >>> >>> - LValueBase() : CallIndex(0), Version(0) {} >>> + LValueBase() : Local{} {} >>> >>> template <class T> >>> - LValueBase(T P, unsigned I = 0, unsigned V = 0) >>> - : Ptr(P), CallIndex(I), Version(V) {} >>> + LValueBase(T P, unsigned I = 0, unsigned V = 0) : Ptr(P), Local{I, V} { >>> + assert(!is<TypeInfoLValue>() && >>> + "don't use this constructor to form a type_info lvalue"); >>> + } >>> + >>> + static LValueBase getTypeInfo(TypeInfoLValue LV, QualType TypeInfo); >>> >>> template <class T> >>> bool is() const { return Ptr.is<T>(); } >>> @@ -78,28 +121,15 @@ public: >>> >>> bool isNull() const; >>> >>> - explicit operator bool () const; >>> + explicit operator bool() const; >>> >>> - PtrTy getPointer() const { >>> - return Ptr; >>> - } >>> + PtrTy getPointer() const { return Ptr; } >>> >>> - unsigned getCallIndex() const { >>> - return CallIndex; >>> - } >>> + unsigned getCallIndex() const; >>> + unsigned getVersion() const; >>> + QualType getTypeInfoType() const; >>> >>> - void setCallIndex(unsigned Index) { >>> - CallIndex = Index; >>> - } >>> - >>> - unsigned getVersion() const { >>> - return Version; >>> - } >>> - >>> - friend bool operator==(const LValueBase &LHS, const LValueBase &RHS) { >>> - return LHS.Ptr == RHS.Ptr && LHS.CallIndex == RHS.CallIndex && >>> - LHS.Version == RHS.Version; >>> - } >>> + friend bool operator==(const LValueBase &LHS, const LValueBase &RHS); >>> friend bool operator!=(const LValueBase &LHS, const LValueBase &RHS) { >>> return !(LHS == RHS); >>> } >>> @@ -107,7 +137,14 @@ public: >>> >>> private: >>> PtrTy Ptr; >>> - unsigned CallIndex, Version; >>> + struct LocalState { >>> + unsigned CallIndex, Version; >>> + }; >>> + union { >>> + LocalState Local; >>> + /// The type std::type_info, if this is a TypeInfoLValue. >>> + void *TypeInfoType; >>> + }; >>> }; >>> >>> /// A FieldDecl or CXXRecordDecl, along with a flag indicating whether we >>> >>> Modified: cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td?rev=360974&r1=360973&r2=360974&view=diff >>> ============================================================================== >>> --- cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td (original) >>> +++ cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td Thu May 16 18:46:05 >>> 2019 >>> @@ -160,6 +160,9 @@ def note_constexpr_access_static_tempora >>> "dynamic_cast of}0 temporary " >>> "is not allowed in a constant expression outside the expression that " >>> "created the temporary">; >>> +def note_constexpr_access_unreadable_object : Note< >>> + "%select{read of|assignment to|increment of|decrement of|member call on|" >>> + "dynamic_cast of}0 object '%1' whose value is not known">; >>> def note_constexpr_modify_global : Note< >>> "a constant expression cannot modify an object that is visible outside " >>> "that expression">; >>> >>> Modified: cfe/trunk/lib/AST/APValue.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/APValue.cpp?rev=360974&r1=360973&r2=360974&view=diff >>> ============================================================================== >>> --- cfe/trunk/lib/AST/APValue.cpp (original) >>> +++ cfe/trunk/lib/AST/APValue.cpp Thu May 16 18:46:05 2019 >>> @@ -20,6 +20,56 @@ >>> #include "llvm/Support/raw_ostream.h" >>> using namespace clang; >>> >>> +/// The identity of a type_info object depends on the canonical unqualified >>> +/// type only. >>> +TypeInfoLValue::TypeInfoLValue(const Type *T) >>> + : T(T->getCanonicalTypeUnqualified().getTypePtr()) {} >>> + >>> +void TypeInfoLValue::print(llvm::raw_ostream &Out, >>> + const PrintingPolicy &Policy) const { >>> + Out << "typeid("; >>> + QualType(getType(), 0).print(Out, Policy); >>> + Out << ")"; >>> +} >>> + >>> +static_assert( >>> + 1 << llvm::PointerLikeTypeTraits<TypeInfoLValue>::NumLowBitsAvailable >>> <= >>> + alignof(const Type *), >>> + "Type is insufficiently aligned"); >>> + >>> +APValue::LValueBase APValue::LValueBase::getTypeInfo(TypeInfoLValue LV, >>> + QualType TypeInfo) { >>> + LValueBase Base; >>> + Base.Ptr = LV; >>> + Base.TypeInfoType = TypeInfo.getAsOpaquePtr(); >>> + return Base; >>> +} >>> + >>> +unsigned APValue::LValueBase::getCallIndex() const { >>> + return is<TypeInfoLValue>() ? 0 : Local.CallIndex; >>> +} >>> + >>> +unsigned APValue::LValueBase::getVersion() const { >>> + return is<TypeInfoLValue>() ? 0 : Local.Version; >>> +} >>> + >>> +QualType APValue::LValueBase::getTypeInfoType() const { >>> + assert(is<TypeInfoLValue>() && "not a type_info lvalue"); >>> + return QualType::getFromOpaquePtr(TypeInfoType); >>> +} >>> + >>> +namespace clang { >>> +bool operator==(const APValue::LValueBase &LHS, >>> + const APValue::LValueBase &RHS) { >>> + if (LHS.Ptr != RHS.Ptr) >>> + return false; >>> + if (LHS.is<TypeInfoLValue>()) >>> + return true; >>> + return LHS.Local.CallIndex == RHS.Local.CallIndex && >>> + LHS.Local.Version == RHS.Local.Version; >>> +} >>> +} >>> + >>> namespace { >>> struct LVBase { >>> APValue::LValueBase Base; >>> @@ -60,6 +110,8 @@ llvm::DenseMapInfo<clang::APValue::LValu >>> >>> namespace clang { >>> llvm::hash_code hash_value(const APValue::LValueBase &Base) { >>> + if (Base.is<TypeInfoLValue>()) >>> + return llvm::hash_value(Base.getOpaqueValue()); >>> return llvm::hash_combine(Base.getOpaqueValue(), Base.getCallIndex(), >>> Base.getVersion()); >>> } >>> @@ -470,7 +522,9 @@ void APValue::printPretty(raw_ostream &O >>> >>> if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) >>> Out << *VD; >>> - else { >>> + else if (TypeInfoLValue TI = Base.dyn_cast<TypeInfoLValue>()) { >>> + TI.print(Out, Ctx.getPrintingPolicy()); >>> + } else { >>> assert(Base.get<const Expr *>() != nullptr && >>> "Expecting non-null Expr"); >>> Base.get<const Expr*>()->printPretty(Out, nullptr, >>> @@ -495,6 +549,9 @@ void APValue::printPretty(raw_ostream &O >>> if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) { >>> Out << *VD; >>> ElemTy = VD->getType(); >>> + } else if (TypeInfoLValue TI = Base.dyn_cast<TypeInfoLValue>()) { >>> + TI.print(Out, Ctx.getPrintingPolicy()); >>> + ElemTy = Base.getTypeInfoType(); >>> } else { >>> const Expr *E = Base.get<const Expr*>(); >>> assert(E != nullptr && "Expecting non-null Expr"); >>> >>> Modified: cfe/trunk/lib/AST/ExprConstant.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=360974&r1=360973&r2=360974&view=diff >>> ============================================================================== >>> --- cfe/trunk/lib/AST/ExprConstant.cpp (original) >>> +++ cfe/trunk/lib/AST/ExprConstant.cpp Thu May 16 18:46:05 2019 >>> @@ -87,6 +87,9 @@ namespace { >>> return D->getType(); >>> } >>> >>> + if (TypeInfoLValue TI = B.dyn_cast<TypeInfoLValue>()) >>> + return B.getTypeInfoType(); >>> + >>> const Expr *Base = B.get<const Expr*>(); >>> >>> // For a materialized temporary, the type of the temporary we materialized >>> @@ -1783,6 +1786,9 @@ static bool IsGlobalLValue(APValue::LVal >>> return isa<FunctionDecl>(D); >>> } >>> >>> + if (B.is<TypeInfoLValue>()) >>> + return true; >>> + >>> const Expr *E = B.get<const Expr*>(); >>> switch (E->getStmtClass()) { >>> default: >>> @@ -1800,7 +1806,6 @@ static bool IsGlobalLValue(APValue::LVal >>> case Expr::PredefinedExprClass: >>> case Expr::ObjCStringLiteralClass: >>> case Expr::ObjCEncodeExprClass: >>> - case Expr::CXXTypeidExprClass: >>> case Expr::CXXUuidofExprClass: >>> return true; >>> case Expr::ObjCBoxedExprClass: >>> @@ -1878,9 +1883,9 @@ static void NoteLValueLocation(EvalInfo >>> const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>(); >>> if (VD) >>> Info.Note(VD->getLocation(), diag::note_declared_at); >>> - else >>> - Info.Note(Base.get<const Expr*>()->getExprLoc(), >>> - diag::note_constexpr_temporary_here); >>> + else if (const Expr *E = Base.dyn_cast<const Expr*>()) >>> + Info.Note(E->getExprLoc(), diag::note_constexpr_temporary_here); >>> + // We have no information to show for a typeid(T) object. >>> } >>> >>> /// Check that this reference or pointer core constant expression is a valid >>> @@ -3404,7 +3409,7 @@ static CompleteObject findCompleteObject >>> >>> if (!Frame) { >>> if (const MaterializeTemporaryExpr *MTE = >>> - dyn_cast<MaterializeTemporaryExpr>(Base)) { >>> + dyn_cast_or_null<MaterializeTemporaryExpr>(Base)) { >>> assert(MTE->getStorageDuration() == SD_Static && >>> "should have a frame for a non-global materialized temporary"); >>> >>> @@ -3439,7 +3444,13 @@ static CompleteObject findCompleteObject >>> } else { >>> if (!IsAccess) >>> return CompleteObject(LVal.getLValueBase(), nullptr, BaseType); >>> - Info.FFDiag(E); >>> + APValue Val; >>> + LVal.moveInto(Val); >>> + Info.FFDiag(E, diag::note_constexpr_access_unreadable_object) >>> + << AK >>> + << Val.getAsString(Info.Ctx, >>> + Info.Ctx.getLValueReferenceType(LValType)); >>> + NoteLValueLocation(Info, LVal.Base); >>> return CompleteObject(); >>> } >>> } else { >>> @@ -5777,13 +5788,13 @@ public: >>> // - Literals >>> // * CompoundLiteralExpr in C (and in global scope in C++) >>> // * StringLiteral >>> -// * CXXTypeidExpr >>> // * PredefinedExpr >>> // * ObjCStringLiteralExpr >>> // * ObjCEncodeExpr >>> // * AddrLabelExpr >>> // * BlockExpr >>> // * CallExpr for a MakeStringConstant builtin >>> +// - typeid(T) expressions, as TypeInfoLValues >>> // - Locals and temporaries >>> // * MaterializeTemporaryExpr >>> // * Any Expr, with a CallIndex indicating the function in which the >>> temporary >>> @@ -6018,8 +6029,14 @@ LValueExprEvaluator::VisitCompoundLitera >>> } >>> >>> bool LValueExprEvaluator::VisitCXXTypeidExpr(const CXXTypeidExpr *E) { >>> - if (!E->isPotentiallyEvaluated()) >>> - return Success(E); >>> + if (!E->isPotentiallyEvaluated()) { >>> + TypeInfoLValue TypeInfo; >>> + if (E->isTypeOperand()) >>> + TypeInfo = TypeInfoLValue(E->getTypeOperand(Info.Ctx).getTypePtr()); >>> + else >>> + TypeInfo = >>> TypeInfoLValue(E->getExprOperand()->getType().getTypePtr()); >>> + return Success(APValue::LValueBase::getTypeInfo(TypeInfo, >>> E->getType())); >>> + } >>> >>> Info.FFDiag(E, diag::note_constexpr_typeid_polymorphic) >>> << E->getExprOperand()->getType() >>> @@ -6615,9 +6632,11 @@ bool PointerExprEvaluator::VisitBuiltinC >>> if (const ValueDecl *VD = >>> OffsetResult.Base.dyn_cast<const ValueDecl*>()) { >>> BaseAlignment = Info.Ctx.getDeclAlign(VD); >>> + } else if (const Expr *E = OffsetResult.Base.dyn_cast<const Expr >>> *>()) { >>> + BaseAlignment = GetAlignOfExpr(Info, E, UETT_AlignOf); >>> } else { >>> - BaseAlignment = GetAlignOfExpr( >>> - Info, OffsetResult.Base.get<const Expr *>(), UETT_AlignOf); >>> + BaseAlignment = GetAlignOfType( >>> + Info, OffsetResult.Base.getTypeInfoType(), UETT_AlignOf); >>> } >>> >>> if (BaseAlignment < Align) { >>> @@ -8335,6 +8354,10 @@ static bool EvaluateBuiltinConstantPForL >>> if (!isa<StringLiteral>(E)) >>> return false; >>> return LV.getLValueOffset().isZero(); >>> + } else if (Base.is<TypeInfoLValue>()) { >>> + // Surprisingly, GCC considers __builtin_constant_p(&typeid(int)) to >>> + // evaluate to true. >>> + return true; >>> } else { >>> // Any other base is not constant enough for GCC. >>> return false; >>> @@ -8399,6 +8422,8 @@ static QualType getObjectType(APValue::L >>> } else if (const Expr *E = B.get<const Expr*>()) { >>> if (isa<CompoundLiteralExpr>(E)) >>> return E->getType(); >>> + } else if (B.is<TypeInfoLValue>()) { >>> + return B.getTypeInfoType(); >>> } >>> >>> return QualType(); >>> >>> Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=360974&r1=360973&r2=360974&view=diff >>> ============================================================================== >>> --- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original) >>> +++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Thu May 16 18:46:05 2019 >>> @@ -1735,6 +1735,17 @@ ConstantLValueEmitter::tryEmitBase(const >>> return nullptr; >>> } >>> >>> + // Handle typeid(T). >>> + if (TypeInfoLValue TI = base.dyn_cast<TypeInfoLValue>()) { >>> + llvm::Type *StdTypeInfoPtrTy = >>> + CGM.getTypes().ConvertType(base.getTypeInfoType())->getPointerTo(); >>> + llvm::Constant *TypeInfo = >>> + CGM.GetAddrOfRTTIDescriptor(QualType(TI.getType(), 0)); >>> + if (TypeInfo->getType() != StdTypeInfoPtrTy) >>> + TypeInfo = llvm::ConstantExpr::getBitCast(TypeInfo, >>> StdTypeInfoPtrTy); >>> + return TypeInfo; >>> + } >>> + >>> // Otherwise, it must be an expression. >>> return Visit(base.get<const Expr*>()); >>> } >>> >>> Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=360974&r1=360973&r2=360974&view=diff >>> ============================================================================== >>> --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original) >>> +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu May 16 18:46:05 2019 >>> @@ -6424,8 +6424,11 @@ ExprResult Sema::CheckTemplateArgument(N >>> // -- a string literal >>> // -- the result of a typeid expression, or >>> // -- a predefined __func__ variable >>> - if (auto *E = Value.getLValueBase().dyn_cast<const Expr*>()) { >>> - if (isa<CXXUuidofExpr>(E)) { >>> + APValue::LValueBase Base = Value.getLValueBase(); >>> + auto *VD = const_cast<ValueDecl *>(Base.dyn_cast<const ValueDecl >>> *>()); >>> + if (Base && !VD) { >>> + auto *E = Base.dyn_cast<const Expr *>(); >>> + if (E && isa<CXXUuidofExpr>(E)) { >>> Converted = TemplateArgument(ArgResult.get()->IgnoreImpCasts()); >>> break; >>> } >>> @@ -6433,8 +6436,6 @@ ExprResult Sema::CheckTemplateArgument(N >>> << Arg->getSourceRange(); >>> return ExprError(); >>> } >>> - auto *VD = const_cast<ValueDecl *>( >>> - Value.getLValueBase().dyn_cast<const ValueDecl *>()); >>> // -- a subobject >>> if (Value.hasLValuePath() && Value.getLValuePath().size() == 1 && >>> VD && VD->getType()->isArrayType() && >>> >>> Modified: cfe/trunk/test/CXX/drs/dr19xx.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr19xx.cpp?rev=360974&r1=360973&r2=360974&view=diff >>> ============================================================================== >>> --- cfe/trunk/test/CXX/drs/dr19xx.cpp (original) >>> +++ cfe/trunk/test/CXX/drs/dr19xx.cpp Thu May 16 18:46:05 2019 >>> @@ -167,9 +167,14 @@ namespace dr1959 { // dr1959: 3.9 >>> #endif >>> } >>> >>> -namespace dr1968 { // dr1968: yes >>> +namespace dr1968 { // dr1968: no >>> #if __cplusplus >= 201103L >>> - static_assert(&typeid(int) == &typeid(int), ""); // expected-error{{not >>> an integral constant expression}} >>> + // FIXME: According to DR1968, both of these should be considered >>> + // non-constant. >>> + static_assert(&typeid(int) == &typeid(int), ""); >>> + >>> + constexpr const std::type_info *f() { return &typeid(int); } >>> + static_assert(f() == f(), ""); >>> #endif >>> } >>> >>> >>> Modified: cfe/trunk/test/Parser/MicrosoftExtensions.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/MicrosoftExtensions.cpp?rev=360974&r1=360973&r2=360974&view=diff >>> ============================================================================== >>> --- cfe/trunk/test/Parser/MicrosoftExtensions.cpp (original) >>> +++ cfe/trunk/test/Parser/MicrosoftExtensions.cpp Thu May 16 18:46:05 2019 >>> @@ -138,6 +138,8 @@ typedef COM_CLASS_TEMPLATE_REF<struct_wi >>> COM_CLASS_TEMPLATE_REF<int, __uuidof(struct_with_uuid)> good_template_arg; >>> >>> COM_CLASS_TEMPLATE<int, __uuidof(struct_with_uuid)> bad_template_arg; // >>> expected-error {{non-type template argument of type 'const _GUID' is not a >>> constant expression}} >>> +// expected-note@-1 {{read of object '__uuidof(struct_with_uuid)' whose >>> value is not known}} >>> +// expected-note@-2 {{temporary created here}} >>> >>> namespace PR16911 { >>> struct __declspec(uuid("{12345678-1234-1234-1234-1234567890aB}")) uuid; >>> >>> Modified: cfe/trunk/test/SemaCXX/builtin-constant-p.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/builtin-constant-p.cpp?rev=360974&r1=360973&r2=360974&view=diff >>> ============================================================================== >>> --- cfe/trunk/test/SemaCXX/builtin-constant-p.cpp (original) >>> +++ cfe/trunk/test/SemaCXX/builtin-constant-p.cpp Thu May 16 18:46:05 2019 >>> @@ -130,3 +130,8 @@ constexpr int mutate6(bool mutate) { >>> static_assert(mutate6(false) == 11); >>> // Mutation of state outside __builtin_constant_p: evaluates to false. >>> static_assert(mutate6(true) == 10); >>> + >>> +// GCC strangely returns true for the address of a type_info object, >>> despite it >>> +// not being a pointer to the start of a string literal. >>> +namespace std { struct type_info; } >>> +static_assert(__builtin_constant_p(&typeid(int))); >>> >>> Modified: cfe/trunk/test/SemaCXX/typeid.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/typeid.cpp?rev=360974&r1=360973&r2=360974&view=diff >>> ============================================================================== >>> --- cfe/trunk/test/SemaCXX/typeid.cpp (original) >>> +++ cfe/trunk/test/SemaCXX/typeid.cpp Thu May 16 18:46:05 2019 >>> @@ -6,7 +6,7 @@ void f() >>> } >>> >>> namespace std { >>> - class type_info; >>> + struct type_info { const char *name; }; >>> } >>> >>> void g() >>> @@ -27,3 +27,6 @@ void h(int i) { >>> typeid(V); // expected-error{{'typeid' of variably modified type >>> 'char [i]'}} >>> typeid(char [i]); // expected-error{{'typeid' of variably modified type >>> 'char [i]'}} >>> } >>> + >>> +// expected-note@+1 {{read of object 'typeid(int).name' whose value is not >>> known}} >>> +constexpr const char *name = typeid(int).name; // expected-error >>> {{constant expression}} >>> >>> Modified: cfe/trunk/www/cxx_dr_status.html >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?rev=360974&r1=360973&r2=360974&view=diff >>> ============================================================================== >>> --- cfe/trunk/www/cxx_dr_status.html (original) >>> +++ cfe/trunk/www/cxx_dr_status.html Thu May 16 18:46:05 2019 >>> @@ -11623,7 +11623,7 @@ and <I>POD class</I></td> >>> <td><a href="http://wg21.link/cwg1968">1968</a></td> >>> <td>NAD</td> >>> <td>Address of <TT>typeid</TT> in constant expressions</td> >>> - <td class="full" align="center">Yes</td> >>> + <td class="none" align="center">No</td> >>> </tr> >>> <tr class="open" id="1969"> >>> <td><a href="http://wg21.link/cwg1969">1969</a></td> >>> >>> >>> _______________________________________________ >>> cfe-commits mailing list >>> cfe-commits@lists.llvm.org >>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >> >> _______________________________________________ >> cfe-commits mailing list >> cfe-commits@lists.llvm.org >> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits