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

Chris Bieneman via cfe-commits cfe-commits at lists.llvm.org
Thu May 16 22:14:00 PDT 2019


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/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 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-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 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



More information about the cfe-commits mailing list