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