r360974 - Refactor constant evaluation of typeid(T) to track a symbolic type_info

via cfe-commits cfe-commits at lists.llvm.org
Thu May 16 22:50:55 PDT 2019


I'm not sure that is problem. Our internal linux build bot also hit the same problem and it has a 64-bit CPU.

Douglas Yung

-----Original Message-----
From: cfe-commits <cfe-commits-bounces at lists.llvm.org> On Behalf Of Chris Bieneman via cfe-commits
Sent: Thursday, May 16, 2019 22:45
To: Chris Bieneman <chris.bieneman at me.com>
Cc: Richard Smith <richard-llvm at metafoo.co.uk>; cfe-commits at lists.llvm.org
Subject: Re: r360974 - Refactor constant evaluation of typeid(T) to track a symbolic type_info

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.bieneman at 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 at 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 at 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/APVa
>>> lue.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/Di
>>> agnosticASTKinds.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?re
>>> v=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.c
>>> pp?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/CGExprCons
>>> tant.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.cp
>>> p?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/MicrosoftE
>>> xtensions.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 at -1 {{read of object '__uuidof(struct_with_uuid)' 
>>> +whose value is not known}} // expected-note at -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-c
>>> onstant-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.cp
>>> p?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 at +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 at lists.llvm.org
>>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>> 
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at lists.llvm.org
>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
> 

_______________________________________________
cfe-commits mailing list
cfe-commits at lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


More information about the cfe-commits mailing list