r363352 - Revert 363295, it caused PR42276. Also revert follow-ups 363337, 363340.

Nico Weber via cfe-commits cfe-commits at lists.llvm.org
Thu Jun 13 21:05:18 PDT 2019


Author: nico
Date: Thu Jun 13 21:05:17 2019
New Revision: 363352

URL: http://llvm.org/viewvc/llvm-project?rev=363352&view=rev
Log:
Revert 363295, it caused PR42276. Also revert follow-ups 363337, 363340.

Revert 363340 "Remove unused SK_LValueToRValue initialization step."
Revert 363337 "PR23833, DR2140: an lvalue-to-rvalue conversion on a glvalue of type"
Revert 363295 "C++ DR712 and others: handle non-odr-use resulting from an lvalue-to-rvalue conversion applied to a member access or similar not-quite-trivial lvalue expression."

Removed:
    cfe/trunk/test/CXX/basic/basic.def.odr/p2.cpp
    cfe/trunk/test/CodeGenCXX/no-odr-use.cpp
Modified:
    cfe/trunk/include/clang/Sema/Initialization.h
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/CodeGen/CGDecl.cpp
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CGExprAgg.cpp
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp
    cfe/trunk/test/Analysis/nullptr.cpp
    cfe/trunk/test/CXX/drs/dr20xx.cpp
    cfe/trunk/test/CXX/drs/dr21xx.cpp
    cfe/trunk/test/CXX/drs/dr23xx.cpp
    cfe/trunk/test/CXX/drs/dr6xx.cpp
    cfe/trunk/test/CXX/drs/dr7xx.cpp
    cfe/trunk/test/CodeGenCXX/nullptr.cpp
    cfe/trunk/www/cxx_dr_status.html

Modified: cfe/trunk/include/clang/Sema/Initialization.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Initialization.h?rev=363352&r1=363351&r2=363352&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Initialization.h (original)
+++ cfe/trunk/include/clang/Sema/Initialization.h Thu Jun 13 21:05:17 2019
@@ -821,6 +821,9 @@ public:
     /// Perform a conversion adding _Atomic to a type.
     SK_AtomicConversion,
 
+    /// Perform a load from a glvalue, producing an rvalue.
+    SK_LValueToRValue,
+
     /// Perform an implicit conversion sequence.
     SK_ConversionSequence,
 
@@ -1267,6 +1270,12 @@ public:
   /// type.
   void AddAtomicConversionStep(QualType Ty);
 
+  /// Add a new step that performs a load of the given type.
+  ///
+  /// Although the term "LValueToRValue" is conventional, this applies to both
+  /// lvalues and xvalues.
+  void AddLValueToRValueStep(QualType Ty);
+
   /// Add a new step that applies an implicit conversion sequence.
   void AddConversionSequenceStep(const ImplicitConversionSequence &ICS,
                                  QualType T, bool TopLevelOfInitList = false);

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=363352&r1=363351&r2=363352&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Thu Jun 13 21:05:17 2019
@@ -1885,11 +1885,6 @@ ImplicitCastExpr *ImplicitCastExpr::Crea
                                            ExprValueKind VK) {
   unsigned PathSize = (BasePath ? BasePath->size() : 0);
   void *Buffer = C.Allocate(totalSizeToAlloc<CXXBaseSpecifier *>(PathSize));
-  // Per C++ [conv.lval]p3, lvalue-to-rvalue conversions on class and
-  // std::nullptr_t have special semantics not captured by CK_LValueToRValue.
-  assert((Kind != CK_LValueToRValue ||
-          !(T->isNullPtrType() || T->getAsCXXRecordDecl())) &&
-         "invalid type for lvalue-to-rvalue conversion");
   ImplicitCastExpr *E =
     new (Buffer) ImplicitCastExpr(T, Kind, Operand, PathSize, VK);
   if (PathSize)

Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=363352&r1=363351&r2=363352&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Thu Jun 13 21:05:17 2019
@@ -1077,16 +1077,17 @@ static llvm::Constant *constWithPadding(
   return constant;
 }
 
-Address CodeGenModule::createUnnamedGlobalFrom(const VarDecl &D,
-                                               llvm::Constant *Constant,
-                                               CharUnits Align) {
+static Address createUnnamedGlobalFrom(CodeGenModule &CGM, const VarDecl &D,
+                                       CGBuilderTy &Builder,
+                                       llvm::Constant *Constant,
+                                       CharUnits Align) {
   auto FunctionName = [&](const DeclContext *DC) -> std::string {
     if (const auto *FD = dyn_cast<FunctionDecl>(DC)) {
       if (const auto *CC = dyn_cast<CXXConstructorDecl>(FD))
         return CC->getNameAsString();
       if (const auto *CD = dyn_cast<CXXDestructorDecl>(FD))
         return CD->getNameAsString();
-      return getMangledName(FD);
+      return CGM.getMangledName(FD);
     } else if (const auto *OM = dyn_cast<ObjCMethodDecl>(DC)) {
       return OM->getNameAsString();
     } else if (isa<BlockDecl>(DC)) {
@@ -1098,39 +1099,22 @@ Address CodeGenModule::createUnnamedGlob
     }
   };
 
-  // Form a simple per-variable cache of these values in case we find we
-  // want to reuse them.
-  llvm::GlobalVariable *&CacheEntry = InitializerConstants[&D];
-  if (!CacheEntry || CacheEntry->getInitializer() != Constant) {
-    auto *Ty = Constant->getType();
-    bool isConstant = true;
-    llvm::GlobalVariable *InsertBefore = nullptr;
-    unsigned AS =
-        getContext().getTargetAddressSpace(getStringLiteralAddressSpace());
-    llvm::GlobalVariable *GV = new llvm::GlobalVariable(
-        getModule(), Ty, isConstant, llvm::GlobalValue::PrivateLinkage,
-        Constant,
-        "__const." + FunctionName(D.getParentFunctionOrMethod()) + "." +
-            D.getName(),
-        InsertBefore, llvm::GlobalValue::NotThreadLocal, AS);
-    GV->setAlignment(Align.getQuantity());
-    GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
-    CacheEntry = GV;
-  } else if (CacheEntry->getAlignment() < Align.getQuantity()) {
-    CacheEntry->setAlignment(Align.getQuantity());
-  }
-
-  return Address(CacheEntry, Align);
-}
-
-static Address createUnnamedGlobalForMemcpyFrom(CodeGenModule &CGM,
-                                                const VarDecl &D,
-                                                CGBuilderTy &Builder,
-                                                llvm::Constant *Constant,
-                                                CharUnits Align) {
-  Address SrcPtr = CGM.createUnnamedGlobalFrom(D, Constant, Align);
-  llvm::Type *BP = llvm::PointerType::getInt8PtrTy(CGM.getLLVMContext(),
-                                                   SrcPtr.getAddressSpace());
+  auto *Ty = Constant->getType();
+  bool isConstant = true;
+  llvm::GlobalVariable *InsertBefore = nullptr;
+  unsigned AS = CGM.getContext().getTargetAddressSpace(
+      CGM.getStringLiteralAddressSpace());
+  llvm::GlobalVariable *GV = new llvm::GlobalVariable(
+      CGM.getModule(), Ty, isConstant, llvm::GlobalValue::PrivateLinkage,
+      Constant,
+      "__const." + FunctionName(D.getParentFunctionOrMethod()) + "." +
+          D.getName(),
+      InsertBefore, llvm::GlobalValue::NotThreadLocal, AS);
+  GV->setAlignment(Align.getQuantity());
+  GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
+
+  Address SrcPtr = Address(GV, Align);
+  llvm::Type *BP = llvm::PointerType::getInt8PtrTy(CGM.getLLVMContext(), AS);
   if (SrcPtr.getType() != BP)
     SrcPtr = Builder.CreateBitCast(SrcPtr, BP);
   return SrcPtr;
@@ -1213,10 +1197,10 @@ static void emitStoresForConstant(CodeGe
   }
 
   // Copy from a global.
-  Builder.CreateMemCpy(Loc,
-                       createUnnamedGlobalForMemcpyFrom(
-                           CGM, D, Builder, constant, Loc.getAlignment()),
-                       SizeVal, isVolatile);
+  Builder.CreateMemCpy(
+      Loc,
+      createUnnamedGlobalFrom(CGM, D, Builder, constant, Loc.getAlignment()),
+      SizeVal, isVolatile);
 }
 
 static void emitStoresForZeroInit(CodeGenModule &CGM, const VarDecl &D,
@@ -1779,10 +1763,10 @@ void CodeGenFunction::EmitAutoVarInit(co
       llvm::PHINode *Cur = Builder.CreatePHI(Begin.getType(), 2, "vla.cur");
       Cur->addIncoming(Begin.getPointer(), OriginBB);
       CharUnits CurAlign = Loc.getAlignment().alignmentOfArrayElement(EltSize);
-      Builder.CreateMemCpy(Address(Cur, CurAlign),
-                           createUnnamedGlobalForMemcpyFrom(
-                               CGM, D, Builder, Constant, ConstantAlign),
-                           BaseSizeInChars, isVolatile);
+      Builder.CreateMemCpy(
+          Address(Cur, CurAlign),
+          createUnnamedGlobalFrom(CGM, D, Builder, Constant, ConstantAlign),
+          BaseSizeInChars, isVolatile);
       llvm::Value *Next =
           Builder.CreateInBoundsGEP(Int8Ty, Cur, BaseSizeInChars, "vla.next");
       llvm::Value *Done = Builder.CreateICmpEQ(Next, End, "vla-init.isdone");

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=363352&r1=363351&r2=363352&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Thu Jun 13 21:05:17 2019
@@ -1422,11 +1422,10 @@ static ConstantEmissionKind checkVarType
 }
 
 /// Try to emit a reference to the given value without producing it as
-/// an l-value.  This is just an optimization, but it avoids us needing
-/// to emit global copies of variables if they're named without triggering
-/// a formal use in a context where we can't emit a direct reference to them,
-/// for instance if a block or lambda or a member of a local class uses a
-/// const int variable or constexpr variable from an enclosing function.
+/// an l-value.  This is actually more than an optimization: we can't
+/// produce an l-value for variables that we never actually captured
+/// in a block or lambda, which means const int variables or constexpr
+/// literals or similar.
 CodeGenFunction::ConstantEmission
 CodeGenFunction::tryEmitAsConstant(DeclRefExpr *refExpr) {
   ValueDecl *value = refExpr->getDecl();
@@ -2451,97 +2450,33 @@ static LValue EmitGlobalNamedRegister(co
   return LValue::MakeGlobalReg(Address(Ptr, Alignment), VD->getType());
 }
 
-/// Determine whether we can emit a reference to \p VD from the current
-/// context, despite not necessarily having seen an odr-use of the variable in
-/// this context.
-static bool canEmitSpuriousReferenceToVariable(CodeGenFunction &CGF,
-                                               const DeclRefExpr *E,
-                                               const VarDecl *VD,
-                                               bool IsConstant) {
-  // For a variable declared in an enclosing scope, do not emit a spurious
-  // reference even if we have a capture, as that will emit an unwarranted
-  // reference to our capture state, and will likely generate worse code than
-  // emitting a local copy.
-  if (E->refersToEnclosingVariableOrCapture())
-    return false;
-
-  // For a local declaration declared in this function, we can always reference
-  // it even if we don't have an odr-use.
-  if (VD->hasLocalStorage()) {
-    return VD->getDeclContext() ==
-           dyn_cast_or_null<DeclContext>(CGF.CurCodeDecl);
-  }
-
-  // For a global declaration, we can emit a reference to it if we know
-  // for sure that we are able to emit a definition of it.
-  VD = VD->getDefinition(CGF.getContext());
-  if (!VD)
-    return false;
-
-  // Don't emit a spurious reference if it might be to a variable that only
-  // exists on a different device / target.
-  // FIXME: This is unnecessarily broad. Check whether this would actually be a
-  // cross-target reference.
-  if (CGF.getLangOpts().OpenMP || CGF.getLangOpts().CUDA ||
-      CGF.getLangOpts().OpenCL) {
-    return false;
-  }
-
-  // We can emit a spurious reference only if the linkage implies that we'll
-  // be emitting a non-interposable symbol that will be retained until link
-  // time.
-  switch (CGF.CGM.getLLVMLinkageVarDefinition(VD, IsConstant)) {
-  case llvm::GlobalValue::ExternalLinkage:
-  case llvm::GlobalValue::LinkOnceODRLinkage:
-  case llvm::GlobalValue::WeakODRLinkage:
-  case llvm::GlobalValue::InternalLinkage:
-  case llvm::GlobalValue::PrivateLinkage:
-    return true;
-  default:
-    return false;
-  }
-}
-
 LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
   const NamedDecl *ND = E->getDecl();
   QualType T = E->getType();
 
-  assert(E->isNonOdrUse() != NOUR_Unevaluated &&
-         "should not emit an unevaluated operand");
-
   if (const auto *VD = dyn_cast<VarDecl>(ND)) {
     // Global Named registers access via intrinsics only
     if (VD->getStorageClass() == SC_Register &&
         VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())
       return EmitGlobalNamedRegister(VD, CGM);
 
-    // If this DeclRefExpr does not constitute an odr-use of the variable,
-    // we're not permitted to emit a reference to it in general, and it might
-    // not be captured if capture would be necessary for a use. Emit the
-    // constant value directly instead.
-    if (E->isNonOdrUse() == NOUR_Constant &&
-        (VD->getType()->isReferenceType() ||
-         !canEmitSpuriousReferenceToVariable(*this, E, VD, true))) {
-      VD->getAnyInitializer(VD);
-      llvm::Constant *Val = ConstantEmitter(*this).emitAbstract(
-          E->getLocation(), *VD->evaluateValue(), VD->getType());
-      assert(Val && "failed to emit constant expression");
-
-      Address Addr = Address::invalid();
-      if (!VD->getType()->isReferenceType()) {
-        // Spill the constant value to a global.
-        Addr = CGM.createUnnamedGlobalFrom(*VD, Val,
-                                           getContext().getDeclAlign(VD));
-      } else {
-        // Should we be using the alignment of the constant pointer we emitted?
-        CharUnits Alignment =
-            getNaturalTypeAlignment(E->getType(),
-                                    /* BaseInfo= */ nullptr,
-                                    /* TBAAInfo= */ nullptr,
-                                    /* forPointeeType= */ true);
-        Addr = Address(Val, Alignment);
-      }
-      return MakeAddrLValue(Addr, T, AlignmentSource::Decl);
+    // A DeclRefExpr for a reference initialized by a constant expression can
+    // appear without being odr-used. Directly emit the constant initializer.
+    VD->getAnyInitializer(VD);
+    if (E->isNonOdrUse() == NOUR_Constant && VD->getType()->isReferenceType()) {
+      llvm::Constant *Val =
+        ConstantEmitter(*this).emitAbstract(E->getLocation(),
+                                            *VD->evaluateValue(),
+                                            VD->getType());
+      assert(Val && "failed to emit reference constant expression");
+      // FIXME: Eventually we will want to emit vector element references.
+
+      // Should we be using the alignment of the constant pointer we emitted?
+      CharUnits Alignment = getNaturalTypeAlignment(E->getType(),
+                                                    /* BaseInfo= */ nullptr,
+                                                    /* TBAAInfo= */ nullptr,
+                                                    /* forPointeeType= */ true);
+      return MakeAddrLValue(Address(Val, Alignment), T, AlignmentSource::Decl);
     }
 
     // FIXME: Handle other kinds of non-odr-use DeclRefExprs.
@@ -2577,7 +2512,7 @@ LValue CodeGenFunction::EmitDeclRefLValu
   // FIXME: We should be able to assert this for FunctionDecls as well!
   // FIXME: We should be able to assert this for all DeclRefExprs, not just
   // those with a valid source location.
-  assert((ND->isUsed(false) || !isa<VarDecl>(ND) || E->isNonOdrUse() ||
+  assert((ND->isUsed(false) || !isa<VarDecl>(ND) ||
           !E->getLocation().isValid()) &&
          "Should not use decl without marking it used!");
 

Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=363352&r1=363351&r2=363352&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Thu Jun 13 21:05:17 2019
@@ -1352,8 +1352,7 @@ static bool isSimpleZero(const Expr *E,
   // (int*)0 - Null pointer expressions.
   if (const CastExpr *ICE = dyn_cast<CastExpr>(E))
     return ICE->getCastKind() == CK_NullToPointer &&
-           CGF.getTypes().isPointerZeroInitializable(E->getType()) &&
-           !E->HasSideEffects(CGF.getContext());
+        CGF.getTypes().isPointerZeroInitializable(E->getType());
   // '\0'
   if (const CharacterLiteral *CL = dyn_cast<CharacterLiteral>(E))
     return CL->getValue() == 0;

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=363352&r1=363351&r2=363352&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Thu Jun 13 21:05:17 2019
@@ -2148,14 +2148,14 @@ Value *ScalarExprEmitter::VisitCastExpr(
 
   case CK_NullToPointer:
     if (MustVisitNullValue(E))
-      CGF.EmitIgnoredExpr(E);
+      (void) Visit(E);
 
     return CGF.CGM.getNullPointer(cast<llvm::PointerType>(ConvertType(DestTy)),
                               DestTy);
 
   case CK_NullToMemberPointer: {
     if (MustVisitNullValue(E))
-      CGF.EmitIgnoredExpr(E);
+      (void) Visit(E);
 
     const MemberPointerType *MPT = CE->getType()->getAs<MemberPointerType>();
     return CGF.CGM.getCXXABI().EmitNullMemberPointer(MPT);

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=363352&r1=363351&r2=363352&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Thu Jun 13 21:05:17 2019
@@ -362,10 +362,6 @@ private:
   llvm::SmallVector<std::pair<llvm::GlobalValue *, llvm::Constant *>, 8>
     GlobalValReplacements;
 
-  /// Variables for which we've emitted globals containing their constant
-  /// values along with the corresponding globals, for opportunistic reuse.
-  llvm::DenseMap<const VarDecl*, llvm::GlobalVariable*> InitializerConstants;
-
   /// Set of global decls for which we already diagnosed mangled name conflict.
   /// Required to not issue a warning (on a mangling conflict) multiple times
   /// for the same decl.
@@ -627,9 +623,6 @@ public:
     StaticLocalDeclGuardMap[D] = C;
   }
 
-  Address createUnnamedGlobalFrom(const VarDecl &D, llvm::Constant *Constant,
-                                  CharUnits Align);
-
   bool lookupRepresentativeDecl(StringRef MangledName,
                                 GlobalDecl &Result) const;
 

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=363352&r1=363351&r2=363352&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Jun 13 21:05:17 2019
@@ -635,10 +635,8 @@ ExprResult Sema::DefaultLvalueConversion
   if (E->getType().getObjCLifetime() == Qualifiers::OCL_Weak)
     Cleanup.setExprNeedsCleanups(true);
 
-  // C++ [conv.lval]p3:
-  //   If T is cv std::nullptr_t, the result is a null pointer constant.
-  CastKind CK = T->isNullPtrType() ? CK_NullToPointer : CK_LValueToRValue;
-  Res = ImplicitCastExpr::Create(Context, T, CK, E, nullptr, VK_RValue);
+  Res = ImplicitCastExpr::Create(Context, T, CK_LValueToRValue, E, nullptr,
+                                 VK_RValue);
 
   // C11 6.3.2.1p2:
   //   ... if the lvalue has atomic type, the value has the non-atomic version
@@ -15808,32 +15806,6 @@ QualType Sema::getCapturedDeclRefType(Va
   return DeclRefType;
 }
 
-namespace {
-// Helper to copy the template arguments from a DeclRefExpr or MemberExpr.
-// The produced TemplateArgumentListInfo* points to data stored within this
-// object, so should only be used in contexts where the pointer will not be
-// used after the CopiedTemplateArgs object is destroyed.
-class CopiedTemplateArgs {
-  bool HasArgs;
-  TemplateArgumentListInfo TemplateArgStorage;
-public:
-  template<typename RefExpr>
-  CopiedTemplateArgs(RefExpr *E) : HasArgs(E->hasExplicitTemplateArgs()) {
-    if (HasArgs)
-      E->copyTemplateArgumentsInto(TemplateArgStorage);
-  }
-  operator TemplateArgumentListInfo*()
-#ifdef __has_cpp_attribute
-#if __has_cpp_attribute(clang::lifetimebound)
-  [[clang::lifetimebound]]
-#endif
-#endif
-  {
-    return HasArgs ? &TemplateArgStorage : nullptr;
-  }
-};
-}
-
 /// Walk the set of potential results of an expression and mark them all as
 /// non-odr-uses if they satisfy the side-conditions of the NonOdrUseReason.
 ///
@@ -15925,11 +15897,16 @@ static ExprResult rebuildPotentialResult
 
     // Rebuild as a non-odr-use DeclRefExpr.
     MarkNotOdrUsed();
+    TemplateArgumentListInfo TemplateArgStorage, *TemplateArgs = nullptr;
+    if (DRE->hasExplicitTemplateArgs()) {
+      DRE->copyTemplateArgumentsInto(TemplateArgStorage);
+      TemplateArgs = &TemplateArgStorage;
+    }
     return DeclRefExpr::Create(
         S.Context, DRE->getQualifierLoc(), DRE->getTemplateKeywordLoc(),
         DRE->getDecl(), DRE->refersToEnclosingVariableOrCapture(),
         DRE->getNameInfo(), DRE->getType(), DRE->getValueKind(),
-        DRE->getFoundDecl(), CopiedTemplateArgs(DRE), NOUR);
+        DRE->getFoundDecl(), TemplateArgs, NOUR);
   }
 
   case Expr::FunctionParmPackExprClass: {
@@ -15947,107 +15924,52 @@ static ExprResult rebuildPotentialResult
     break;
   }
 
+  // FIXME: Implement these.
   //   -- If e is a subscripting operation with an array operand...
-  case Expr::ArraySubscriptExprClass: {
-    auto *ASE = cast<ArraySubscriptExpr>(E);
-    Expr *OldBase = ASE->getBase()->IgnoreImplicit();
-    if (!OldBase->getType()->isArrayType())
-      break;
-    ExprResult Base = Rebuild(OldBase);
-    if (!Base.isUsable())
-      return Base;
-    Expr *LHS = ASE->getBase() == ASE->getLHS() ? Base.get() : ASE->getLHS();
-    Expr *RHS = ASE->getBase() == ASE->getRHS() ? Base.get() : ASE->getRHS();
-    SourceLocation LBracketLoc = ASE->getBeginLoc(); // FIXME: Not stored.
-    return S.ActOnArraySubscriptExpr(nullptr, LHS, LBracketLoc, RHS,
-                                     ASE->getRBracketLoc());
-  }
+  //   -- If e is a class member access expression [...] naming a non-static
+  //      data member...
 
+  //   -- If e is a class member access expression naming a static data member,
+  //      ...
   case Expr::MemberExprClass: {
     auto *ME = cast<MemberExpr>(E);
-    // -- If e is a class member access expression [...] naming a non-static
-    //    data member...
-    if (isa<FieldDecl>(ME->getMemberDecl())) {
-      ExprResult Base = Rebuild(ME->getBase());
-      if (!Base.isUsable())
-        return Base;
-      return MemberExpr::Create(
-          S.Context, Base.get(), ME->isArrow(), ME->getOperatorLoc(),
-          ME->getQualifierLoc(), ME->getTemplateKeywordLoc(),
-          ME->getMemberDecl(), ME->getFoundDecl(), ME->getMemberNameInfo(),
-          CopiedTemplateArgs(ME), ME->getType(), ME->getValueKind(),
-          ME->getObjectKind(), ME->isNonOdrUse());
-    }
-
     if (ME->getMemberDecl()->isCXXInstanceMember())
+      // FIXME: Recurse to the left-hand side.
       break;
 
-    // -- If e is a class member access expression naming a static data member,
-    //    ...
     if (ME->isNonOdrUse() || IsPotentialResultOdrUsed(ME->getMemberDecl()))
       break;
 
     // Rebuild as a non-odr-use MemberExpr.
     MarkNotOdrUsed();
+    TemplateArgumentListInfo TemplateArgStorage, *TemplateArgs = nullptr;
+    if (ME->hasExplicitTemplateArgs()) {
+      ME->copyTemplateArgumentsInto(TemplateArgStorage);
+      TemplateArgs = &TemplateArgStorage;
+    }
     return MemberExpr::Create(
         S.Context, ME->getBase(), ME->isArrow(), ME->getOperatorLoc(),
         ME->getQualifierLoc(), ME->getTemplateKeywordLoc(), ME->getMemberDecl(),
-        ME->getFoundDecl(), ME->getMemberNameInfo(), CopiedTemplateArgs(ME),
+        ME->getFoundDecl(), ME->getMemberNameInfo(), TemplateArgs,
         ME->getType(), ME->getValueKind(), ME->getObjectKind(), NOUR);
     return ExprEmpty();
   }
 
-  case Expr::BinaryOperatorClass: {
-    auto *BO = cast<BinaryOperator>(E);
-    Expr *LHS = BO->getLHS();
-    Expr *RHS = BO->getRHS();
-    // -- If e is a pointer-to-member expression of the form e1 .* e2 ...
-    if (BO->getOpcode() == BO_PtrMemD) {
-      ExprResult Sub = Rebuild(LHS);
-      if (!Sub.isUsable())
-        return Sub;
-      LHS = Sub.get();
-    //   -- If e is a comma expression, ...
-    } else if (BO->getOpcode() == BO_Comma) {
-      ExprResult Sub = Rebuild(RHS);
-      if (!Sub.isUsable())
-        return Sub;
-      RHS = Sub.get();
-    } else {
-      break;
-    }
-    return S.BuildBinOp(nullptr, BO->getOperatorLoc(), BO->getOpcode(),
-                        LHS, RHS);
-  }
+  // FIXME: Implement this.
+  //   -- If e is a pointer-to-member expression of the form e1 .* e2 ...
 
   //   -- If e has the form (e1)...
   case Expr::ParenExprClass: {
-    auto *PE = cast<ParenExpr>(E);
+    auto *PE = dyn_cast<ParenExpr>(E);
     ExprResult Sub = Rebuild(PE->getSubExpr());
     if (!Sub.isUsable())
       return Sub;
     return S.ActOnParenExpr(PE->getLParen(), PE->getRParen(), Sub.get());
   }
 
+  // FIXME: Implement these.
   //   -- If e is a glvalue conditional expression, ...
-  // We don't apply this to a binary conditional operator. FIXME: Should we?
-  case Expr::ConditionalOperatorClass: {
-    auto *CO = cast<ConditionalOperator>(E);
-    ExprResult LHS = Rebuild(CO->getLHS());
-    if (LHS.isInvalid())
-      return ExprError();
-    ExprResult RHS = Rebuild(CO->getRHS());
-    if (RHS.isInvalid())
-      return ExprError();
-    if (!LHS.isUsable() && !RHS.isUsable())
-      return ExprEmpty();
-    if (!LHS.isUsable())
-      LHS = CO->getLHS();
-    if (!RHS.isUsable())
-      RHS = CO->getRHS();
-    return S.ActOnConditionalOp(CO->getQuestionLoc(), CO->getColonLoc(),
-                                CO->getCond(), LHS.get(), RHS.get());
-  }
+  //   -- If e is a comma expression, ...
 
   // [Clang extension]
   //   -- If e has the form __extension__ e1...
@@ -16066,7 +15988,7 @@ static ExprResult rebuildPotentialResult
   //   -- If e has the form _Generic(...), the set of potential results is the
   //      union of the sets of potential results of the associated expressions.
   case Expr::GenericSelectionExprClass: {
-    auto *GSE = cast<GenericSelectionExpr>(E);
+    auto *GSE = dyn_cast<GenericSelectionExpr>(E);
 
     SmallVector<Expr *, 4> AssocExprs;
     bool AnyChanged = false;
@@ -16094,7 +16016,7 @@ static ExprResult rebuildPotentialResult
   //      results is the union of the sets of potential results of the
   //      second and third subexpressions.
   case Expr::ChooseExprClass: {
-    auto *CE = cast<ChooseExpr>(E);
+    auto *CE = dyn_cast<ChooseExpr>(E);
 
     ExprResult LHS = Rebuild(CE->getLHS());
     if (LHS.isInvalid())
@@ -16117,38 +16039,13 @@ static ExprResult rebuildPotentialResult
 
   // Step through non-syntactic nodes.
   case Expr::ConstantExprClass: {
-    auto *CE = cast<ConstantExpr>(E);
+    auto *CE = dyn_cast<ConstantExpr>(E);
     ExprResult Sub = Rebuild(CE->getSubExpr());
     if (!Sub.isUsable())
       return Sub;
     return ConstantExpr::Create(S.Context, Sub.get());
   }
 
-  // We could mostly rely on the recursive rebuilding to rebuild implicit
-  // casts, but not at the top level, so rebuild them here.
-  case Expr::ImplicitCastExprClass: {
-    auto *ICE = cast<ImplicitCastExpr>(E);
-    // Only step through the narrow set of cast kinds we expect to encounter.
-    // Anything else suggests we've left the region in which potential results
-    // can be found.
-    switch (ICE->getCastKind()) {
-    case CK_NoOp:
-    case CK_DerivedToBase:
-    case CK_UncheckedDerivedToBase: {
-      ExprResult Sub = Rebuild(ICE->getSubExpr());
-      if (!Sub.isUsable())
-        return Sub;
-      CXXCastPath Path(ICE->path());
-      return S.ImpCastExprToType(Sub.get(), ICE->getType(), ICE->getCastKind(),
-                                 ICE->getValueKind(), &Path);
-    }
-
-    default:
-      break;
-    }
-    break;
-  }
-
   default:
     break;
   }

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=363352&r1=363351&r2=363352&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Thu Jun 13 21:05:17 2019
@@ -3282,6 +3282,7 @@ void InitializationSequence::Step::Destr
   case SK_QualificationConversionXValue:
   case SK_QualificationConversionLValue:
   case SK_AtomicConversion:
+  case SK_LValueToRValue:
   case SK_ListInitialization:
   case SK_UnwrapInitList:
   case SK_RewrapInitList:
@@ -3465,6 +3466,15 @@ void InitializationSequence::AddAtomicCo
   Steps.push_back(S);
 }
 
+void InitializationSequence::AddLValueToRValueStep(QualType Ty) {
+  assert(!Ty.hasQualifiers() && "rvalues may not have qualifiers");
+
+  Step S;
+  S.Kind = SK_LValueToRValue;
+  S.Type = Ty;
+  Steps.push_back(S);
+}
+
 void InitializationSequence::AddConversionSequenceStep(
     const ImplicitConversionSequence &ICS, QualType T,
     bool TopLevelOfInitList) {
@@ -7495,6 +7505,7 @@ ExprResult InitializationSequence::Perfo
   case SK_QualificationConversionXValue:
   case SK_QualificationConversionRValue:
   case SK_AtomicConversion:
+  case SK_LValueToRValue:
   case SK_ConversionSequence:
   case SK_ConversionSequenceNoNarrowing:
   case SK_ListInitialization:
@@ -7766,6 +7777,14 @@ ExprResult InitializationSequence::Perfo
       break;
     }
 
+    case SK_LValueToRValue: {
+      assert(CurInit.get()->isGLValue() && "cannot load from a prvalue");
+      CurInit = ImplicitCastExpr::Create(S.Context, Step->Type,
+                                         CK_LValueToRValue, CurInit.get(),
+                                         /*BasePath=*/nullptr, VK_RValue);
+      break;
+    }
+
     case SK_ConversionSequence:
     case SK_ConversionSequenceNoNarrowing: {
       if (const auto *FromPtrType =
@@ -8987,6 +9006,10 @@ void InitializationSequence::dump(raw_os
       OS << "non-atomic-to-atomic conversion";
       break;
 
+    case SK_LValueToRValue:
+      OS << "load (lvalue to rvalue)";
+      break;
+
     case SK_ConversionSequence:
       OS << "implicit conversion sequence (";
       S->ICS->dump(); // FIXME: use OS

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp?rev=363352&r1=363351&r2=363352&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineC.cpp Thu Jun 13 21:05:17 2019
@@ -378,6 +378,7 @@ void ExprEngine::VisitCast(const CastExp
       case CK_BitCast:
       case CK_AddressSpaceConversion:
       case CK_BooleanToSignedIntegral:
+      case CK_NullToPointer:
       case CK_IntegralToPointer:
       case CK_PointerToIntegral: {
         SVal V = state->getSVal(Ex, LCtx);
@@ -502,12 +503,6 @@ void ExprEngine::VisitCast(const CastExp
         Bldr.generateNode(CastE, Pred, state);
         continue;
       }
-      case CK_NullToPointer: {
-        SVal V = svalBuilder.makeNull();
-        state = state->BindExpr(CastE, LCtx, V);
-        Bldr.generateNode(CastE, Pred, state);
-        continue;
-      }
       case CK_NullToMemberPointer: {
         SVal V = svalBuilder.getMemberPointer(nullptr);
         state = state->BindExpr(CastE, LCtx, V);

Modified: cfe/trunk/test/Analysis/nullptr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/nullptr.cpp?rev=363352&r1=363351&r2=363352&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/nullptr.cpp (original)
+++ cfe/trunk/test/Analysis/nullptr.cpp Thu Jun 13 21:05:17 2019
@@ -128,10 +128,18 @@ void shouldNotCrash() {
   decltype(nullptr) p; // expected-note{{'p' declared without an initial value}}
   if (getSymbol()) // expected-note   {{Assuming the condition is false}}
                    // expected-note at -1{{Taking false branch}}
+                   // expected-note at -2{{Assuming the condition is false}}
+                   // expected-note at -3{{Taking false branch}}
+                   // expected-note at -4{{Assuming the condition is true}}
+                   // expected-note at -5{{Taking true branch}}
+    invokeF(p); // expected-warning{{1st function call argument is an uninitialized value}}
+                // expected-note at -1{{1st function call argument is an uninitialized value}}
+  if (getSymbol()) // expected-note   {{Assuming the condition is false}}
+                   // expected-note at -1{{Taking false branch}}
                    // expected-note at -2{{Assuming the condition is true}}
                    // expected-note at -3{{Taking true branch}}
-    invokeF(p);    // expected-note   {{Calling 'invokeF'}}
-                   // expected-note at -1{{Passing null pointer value via 1st parameter 'x'}}
+    invokeF(nullptr); // expected-note   {{Calling 'invokeF'}}
+                      // expected-note at -1{{Passing null pointer value via 1st parameter 'x'}}
   if (getSymbol()) {  // expected-note  {{Assuming the condition is true}}
                       // expected-note at -1{{Taking true branch}}
     X *xx = Type().x; // expected-note   {{Null pointer value stored to field 'x'}}

Removed: cfe/trunk/test/CXX/basic/basic.def.odr/p2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.def.odr/p2.cpp?rev=363351&view=auto
==============================================================================
--- cfe/trunk/test/CXX/basic/basic.def.odr/p2.cpp (original)
+++ cfe/trunk/test/CXX/basic/basic.def.odr/p2.cpp (removed)
@@ -1,80 +0,0 @@
-// RUN: %clang_cc1 -std=c++98 %s -Wno-unused -verify
-// RUN: %clang_cc1 -std=c++11 %s -Wno-unused -verify
-// RUN: %clang_cc1 -std=c++2a %s -Wno-unused -verify
-
-void use(int);
-
-void f() {
-  const int a = 1; // expected-note {{here}}
-
-#if __cplusplus >= 201103L
-  constexpr int arr[3] = {1, 2, 3}; // expected-note 2{{here}}
-
-  struct S { int x; int f() const; };
-  constexpr S s = {0}; // expected-note 3{{here}}
-  constexpr S *ps = nullptr;
-  S *const &psr = ps; // expected-note 2{{here}}
-#endif
-
-  struct Inner {
-    void test(int i) {
-      // id-expression
-      use(a);
-
-#if __cplusplus >= 201103L
-      // subscripting operation with an array operand
-      use(arr[i]);
-      use(i[arr]);
-      use((+arr)[i]); // expected-error {{reference to local variable}}
-      use(i[+arr]); // expected-error {{reference to local variable}}
-
-      // class member access naming non-static data member
-      use(s.x);
-      use(s.f()); // expected-error {{reference to local variable}}
-      use((&s)->x); // expected-error {{reference to local variable}}
-      use(ps->x); // ok (lvalue-to-rvalue conversion applied to id-expression)
-      use(psr->x); // expected-error {{reference to local variable}}
-
-      // class member access naming a static data member
-      // FIXME: How to test this?
-
-      // pointer-to-member expression
-      use(s.*&S::x);
-      use((s.*&S::f)()); // expected-error {{reference to local variable}}
-      use(ps->*&S::x); // ok (lvalue-to-rvalue conversion applied to id-expression)
-      use(psr->*&S::x); // expected-error {{reference to local variable}}
-#endif
-
-      // parentheses
-      use((a));
-#if __cplusplus >= 201103L
-      use((s.x));
-#endif
-
-      // glvalue conditional expression
-      use(i ? a : a);
-      use(i ? i : a);
-
-      // comma expression
-      use((i, a));
-      // FIXME: This is not an odr-use because it is a discarded-value
-      // expression applied to an expression whose potential result is 'a'.
-      use((a, a)); // expected-error {{reference to local variable}}
-
-      // (and combinations thereof)
-      use(a ? (i, a) : a);
-#if __cplusplus >= 201103L
-      use(a ? (i, a) : arr[a ? s.x : arr[a]]);
-#endif
-    }
-  };
-}
-
-// FIXME: Test that this behaves properly.
-namespace std_example {
-  struct S { static const int x = 0, y = 0; };
-  const int &f(const int &r);
-  bool b;
-  int n = b ? (1, S::x)
-            : f(S::y);
-}

Modified: cfe/trunk/test/CXX/drs/dr20xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr20xx.cpp?rev=363352&r1=363351&r2=363352&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr20xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr20xx.cpp Thu Jun 13 21:05:17 2019
@@ -4,204 +4,11 @@
 // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++1z -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
 
-#if __cplusplus < 201103L
-#define static_assert(...) _Static_assert(__VA_ARGS__)
-#endif
+// expected-no-diagnostics
 
-namespace dr2083 { // dr2083: partial
-#if __cplusplus >= 201103L
-  void non_const_mem_ptr() {
-    struct A {
-      int x;
-      int y;
-    };
-    constexpr A a = {1, 2};
-    struct B {
-      int A::*p;
-      constexpr int g() const {
-        // OK, not an odr-use of 'a'.
-        return a.*p;
-      };
-    };
-    static_assert(B{&A::x}.g() == 1, "");
-    static_assert(B{&A::y}.g() == 2, "");
-  }
-#endif
-
-  const int a = 1;
-  int b;
-  // Note, references only get special odr-use / constant initializxer
-  // treatment in C++11 onwards. We continue to apply that even after DR2083.
-  void ref_to_non_const() {
-    int c;
-    const int &ra = a; // expected-note 0-1{{here}}
-    int &rb = b; // expected-note 0-1{{here}}
-    int &rc = c; // expected-note {{here}}
-    struct A {
-      int f() {
-        int a = ra;
-        int b = rb;
 #if __cplusplus < 201103L
-        // expected-error at -3 {{in enclosing function}}
-        // expected-error at -3 {{in enclosing function}}
-#endif
-        int c = rc; // expected-error {{in enclosing function}}
-        return a + b + c;
-      }
-    };
-  }
-
-#if __cplusplus >= 201103L
-  struct NoMut1 { int a, b; };
-  struct NoMut2 { NoMut1 m; };
-  struct NoMut3 : NoMut1 {
-    constexpr NoMut3(int a, int b) : NoMut1{a, b} {}
-  };
-  struct Mut1 {
-    int a;
-    mutable int b;
-  };
-  struct Mut2 { Mut1 m; };
-  struct Mut3 : Mut1 {
-    constexpr Mut3(int a, int b) : Mut1{a, b} {}
-  };
-  void mutable_subobjects() {
-    constexpr NoMut1 nm1 = {1, 2};
-    constexpr NoMut2 nm2 = {1, 2};
-    constexpr NoMut3 nm3 = {1, 2};
-    constexpr Mut1 m1 = {1, 2}; // expected-note {{declared here}}
-    constexpr Mut2 m2 = {1, 2}; // expected-note {{declared here}}
-    constexpr Mut3 m3 = {1, 2}; // expected-note {{declared here}}
-    struct A {
-      void f() {
-        static_assert(nm1.a == 1, "");
-        static_assert(nm2.m.a == 1, "");
-        static_assert(nm3.a == 1, "");
-        // Can't even access a non-mutable member of a variable containing mutable fields.
-        static_assert(m1.a == 1, ""); // expected-error {{enclosing function}}
-        static_assert(m2.m.a == 1, ""); // expected-error {{enclosing function}}
-        static_assert(m3.a == 1, ""); // expected-error {{enclosing function}}
-      }
-    };
-  }
-#endif
-
-  void ellipsis() {
-    void ellipsis(...);
-    struct A {};
-    const int n = 0;
-#if __cplusplus >= 201103L
-    constexpr
-#endif
-      A a = {}; // expected-note {{here}}
-    struct B {
-      void f() {
-        ellipsis(n);
-        // Even though this is technically modelled as an lvalue-to-rvalue
-        // conversion, it calls a constructor and binds 'a' to a reference, so
-        // it results in an odr-use.
-        ellipsis(a); // expected-error {{enclosing function}}
-      }
-    };
-  }
-
-#if __cplusplus >= 201103L
-  void volatile_lval() {
-    struct A { int n; };
-    constexpr A a = {0}; // expected-note {{here}}
-    struct B {
-      void f() {
-        // An lvalue-to-rvalue conversion of a volatile lvalue always results
-        // in odr-use.
-        int A::*p = &A::n;
-        int x = a.*p;
-        volatile int A::*q = p;
-        int y = a.*q; // expected-error {{enclosing function}}
-      }
-    };
-  }
-#endif
-
-  void discarded_lval() {
-    struct A { int x; mutable int y; volatile int z; };
-    A a; // expected-note 1+{{here}}
-    int &r = a.x; // expected-note {{here}}
-    struct B {
-      void f() {
-        a.x; // expected-warning {{unused}}
-        a.*&A::x; // expected-warning {{unused}}
-        true ? a.x : a.y; // expected-warning {{unused}}
-        (void)a.x;
-        a.x, discarded_lval(); // expected-warning {{unused}}
-#if 1 // FIXME: These errors are all incorrect; the above code is valid.
-      // expected-error at -6 {{enclosing function}}
-      // expected-error at -6 {{enclosing function}}
-      // expected-error at -6 2{{enclosing function}}
-      // expected-error at -6 {{enclosing function}}
-      // expected-error at -6 {{enclosing function}}
-#endif
-
-        // 'volatile' qualifier triggers an lvalue-to-rvalue conversion.
-        a.z; // expected-error {{enclosing function}}
-#if __cplusplus < 201103L
-        // expected-warning at -2 {{assign into a variable}}
-#endif
-
-        // References always get "loaded" to determine what they reference,
-        // even if the result is discarded.
-        r; // expected-error {{enclosing function}} expected-warning {{unused}}
-      }
-    };
-  }
-
-  namespace dr_example_1 {
-    extern int globx;
-    int main() {
-      const int &x = globx;
-      struct A {
-#if __cplusplus < 201103L
-        // expected-error at +2 {{enclosing function}} expected-note at -3 {{here}}
-#endif
-        const int *foo() { return &x; }
-      } a;
-      return *a.foo();
-    }
-  }
-
-#if __cplusplus >= 201103L
-  namespace dr_example_2 {
-    struct A {
-      int q;
-      constexpr A(int q) : q(q) {}
-      constexpr A(const A &a) : q(a.q * 2) {} // (note, not called)
-    };
-
-    int main(void) {
-      constexpr A a(42);
-      constexpr int aq = a.q;
-      struct Q {
-        int foo() { return a.q; }
-      } q;
-      return q.foo();
-    }
-
-    // Checking odr-use does not invent an lvalue-to-rvalue conversion (and
-    // hence copy construction) on the potential result variable.
-    struct B {
-      int b = 42;
-      constexpr B() {}
-      constexpr B(const B&) = delete;
-    };
-    void f() {
-      constexpr B b;
-      struct Q {
-        constexpr int foo() const { return b.b; }
-      };
-      static_assert(Q().foo() == 42, "");
-    }
-  }
+#define static_assert(...) _Static_assert(__VA_ARGS__)
 #endif
-}
 
 namespace dr2094 { // dr2094: 5
   struct A { int n; };

Modified: cfe/trunk/test/CXX/drs/dr21xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr21xx.cpp?rev=363352&r1=363351&r2=363352&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr21xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr21xx.cpp Thu Jun 13 21:05:17 2019
@@ -8,19 +8,6 @@
 #define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
 #endif
 
-namespace dr2103 { // dr2103: yes
-  void f() {
-    int a;
-    int &r = a; // expected-note {{here}}
-    struct Inner {
-      void f() {
-        int &s = r; // expected-error {{enclosing function}}
-        (void)s;
-      }
-    };
-  }
-}
-
 namespace dr2120 { // dr2120: 7
   struct A {};
   struct B : A {};
@@ -32,29 +19,6 @@ namespace dr2120 { // dr2120: 7
   static_assert(!__is_standard_layout(E), "");
 }
 
-namespace dr2140 { // dr2140: 9
-#if __cplusplus >= 201103L
-  union U { int a; decltype(nullptr) b; };
-  constexpr int *test(U u) {
-    return u.b;
-  }
-  static_assert(!test({123}), "u.b should be valid even when b is inactive");
-#endif
-}
-
-namespace dr2170 { // dr2170: 9
-#if __cplusplus >= 201103L
-  void f() {
-    constexpr int arr[3] = {1, 2, 3}; // expected-note {{here}}
-    struct S {
-      int get(int n) { return arr[n]; }
-      const int &get_ref(int n) { return arr[n]; } // expected-error {{enclosing function}}
-      // FIXME: expected-warning at -1 {{reference to stack}}
-    };
-  }
-#endif
-}
-
 namespace dr2180 { // dr2180: yes
   class A {
     A &operator=(const A &); // expected-note 0-2{{here}}

Modified: cfe/trunk/test/CXX/drs/dr23xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr23xx.cpp?rev=363352&r1=363351&r2=363352&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr23xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr23xx.cpp Thu Jun 13 21:05:17 2019
@@ -1,45 +1,13 @@
-// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
-// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
-// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
-// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
-// RUN: %clang_cc1 -std=c++2a %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++2a %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
 
 #if __cplusplus <= 201103L
 // expected-no-diagnostics
 #endif
 
-namespace dr2353 { // dr2353: 9
-  struct X {
-    static const int n = 0;
-  };
-
-  // CHECK: FunctionDecl {{.*}} use
-  int use(X x) {
-    // CHECK: MemberExpr {{.*}} .n
-    // CHECK-NOT: non_odr_use
-    // CHECK: DeclRefExpr {{.*}} 'x'
-    // CHECK-NOT: non_odr_use
-    return *&x.n;
-  }
-#pragma clang __debug dump use
-
-  // CHECK: FunctionDecl {{.*}} not_use
-  int not_use(X x) {
-    // CHECK: MemberExpr {{.*}} .n {{.*}} non_odr_use_constant
-    // CHECK: DeclRefExpr {{.*}} 'x'
-    return x.n;
-  }
-#pragma clang __debug dump not_use
-
-  // CHECK: FunctionDecl {{.*}} not_use_2
-  int not_use_2(X *x) {
-    // CHECK: MemberExpr {{.*}} ->n {{.*}} non_odr_use_constant
-    // CHECK: DeclRefExpr {{.*}} 'x'
-    return x->n;
-  }
-#pragma clang __debug dump not_use_2
-}
-
 namespace dr2387 { // dr2387: 9
 #if __cplusplus >= 201402L
   template<int> int a = 0;

Modified: cfe/trunk/test/CXX/drs/dr6xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr6xx.cpp?rev=363352&r1=363351&r2=363352&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr6xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr6xx.cpp Thu Jun 13 21:05:17 2019
@@ -1132,20 +1132,3 @@ namespace dr692 { // dr692: no
     template void f(int*); // expected-error {{ambiguous}}
   }
 }
-
-namespace dr696 { // dr696: yes
-  void f(const int*);
-  void g() {
-    const int N = 10; // expected-note 1+{{here}}
-    struct A {
-      void h() {
-        int arr[N]; (void)arr;
-        f(&N); // expected-error {{declared in enclosing}}
-      }
-    };
-#if __cplusplus >= 201103L
-    (void) [] { int arr[N]; (void)arr; };
-    (void) [] { f(&N); }; // expected-error {{cannot be implicitly captured}} expected-note {{here}}
-#endif
-  }
-}

Modified: cfe/trunk/test/CXX/drs/dr7xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr7xx.cpp?rev=363352&r1=363351&r2=363352&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr7xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr7xx.cpp Thu Jun 13 21:05:17 2019
@@ -17,42 +17,6 @@ namespace dr705 { // dr705: yes
   }
 }
 
-namespace dr712 { // dr712: partial
-  void use(int);
-  void f() {
-    const int a = 0; // expected-note 5{{here}}
-    struct X {
-      void g(bool cond) {
-        use(a);
-        use((a));
-        use(cond ? a : a);
-        use((cond, a)); // expected-warning 2{{unused}} FIXME: should only warn once
-
-        (void)a; // FIXME: expected-error {{declared in enclosing}}
-        (void)(a); // FIXME: expected-error {{declared in enclosing}}
-        (void)(cond ? a : a); // FIXME: expected-error 2{{declared in enclosing}}
-        (void)(cond, a); // FIXME: expected-error {{declared in enclosing}} expected-warning {{unused}}
-      }
-    };
-  }
-
-#if __cplusplus >= 201103L
-  void g() {
-    struct A { int n; };
-    constexpr A a = {0}; // expected-note 2{{here}}
-    struct X {
-      void g(bool cond) {
-        use(a.n);
-        use(a.*&A::n);
-
-        (void)a.n; // FIXME: expected-error {{declared in enclosing}}
-        (void)(a.*&A::n); // FIXME: expected-error {{declared in enclosing}}
-      }
-    };
-  }
-#endif
-}
-
 namespace dr727 { // dr727: partial
   struct A {
     template<typename T> struct C; // expected-note 6{{here}}

Removed: cfe/trunk/test/CodeGenCXX/no-odr-use.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/no-odr-use.cpp?rev=363351&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/no-odr-use.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/no-odr-use.cpp (removed)
@@ -1,27 +0,0 @@
-// RUN: %clang_cc1 -emit-llvm -o - -triple x86_64-linux-gnu %s | FileCheck %s
-
-// CHECK: @__const._Z1fi.a = private unnamed_addr constant {{.*}} { i32 1, [2 x i32] [i32 2, i32 3], [3 x i32] [i32 4, i32 5, i32 6] }
-
-struct A { int x, y[2]; int arr[3]; };
-// CHECK-LABEL: define i32 @_Z1fi(
-int f(int i) {
-  // CHECK: call void {{.*}}memcpy{{.*}}({{.*}}, {{.*}} @__const._Z1fi.a
-  constexpr A a = {1, 2, 3, 4, 5, 6};
-
-  // CHECK-LABEL: define {{.*}}@"_ZZ1fiENK3$_0clEiM1Ai"(
-  return [] (int n, int A::*p) {
-    // CHECK: br i1
-    return (n >= 0
-      // CHECK: getelementptr inbounds [3 x i32], [3 x i32]* getelementptr inbounds ({{.*}} @__const._Z1fi.a, i32 0, i32 2), i64 0, i64 %
-      ? a.arr[n]
-      // CHECK: br i1
-      : (n == -1
-        // CHECK: getelementptr inbounds i8, i8* bitcast ({{.*}} @__const._Z1fi.a to i8*), i64 %
-        // CHECK: bitcast i8* %{{.*}} to i32*
-        // CHECK: load i32
-        ? a.*p
-        // CHECK: getelementptr inbounds [2 x i32], [2 x i32]* getelementptr inbounds ({{.*}} @__const._Z1fi.a, i32 0, i32 1), i64 0, i64 %
-        // CHECK: load i32
-        : a.y[2 - n]));
-  }(i, &A::x);
-}

Modified: cfe/trunk/test/CodeGenCXX/nullptr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/nullptr.cpp?rev=363352&r1=363351&r2=363352&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/nullptr.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/nullptr.cpp Thu Jun 13 21:05:17 2019
@@ -22,50 +22,3 @@ void g() {
 const std::type_info& f2() {
   return typeid(nullptr_t);
 }
-
-union U {
-  int n;
-  nullptr_t b;
-};
-// CHECK-LABEL: define {{.*}}pr23833_a
-// CHECK: store
-// CHECK: load
-// CHECK-NOT: load
-// CHECK: ret i1 false
-bool pr23833_a(U &u) { return u.b; }
-
-// CHECK-LABEL: define {{.*}}pr23833_b
-// CHECK: store
-// CHECK: load
-// CHECK-NOT: load
-// CHECK: ret i8* null
-nullptr_t pr23833_b(nullptr_t &n) { return n; }
-
-struct X1 { operator int*(); };
-struct X2 { operator const nullptr_t&(); };
-
-// CHECK-LABEL: define {{.*}}pr23833_c
-// CHECK: call {{.*}}X1
-// CHECK: call {{.*}}X2
-// CHECK-NOT: load
-// CHECK: ret i32
-int pr23833_c() {
-  return X1() != X2();
-}
-
-// CHECK-LABEL: define {{.*}}pr23833_d
-// CHECK: call {{.*}}X2
-// CHECK-NOT: load
-// CHECK: store
-// CHECK: load
-// CHECK: ret i32*
-int *pr23833_d() {
-  int *p = X2();
-  return p;
-}
-
-namespace PR39528 {
-  constexpr nullptr_t null = nullptr;
-  void f(nullptr_t);
-  void g() { f(null); }
-}

Modified: cfe/trunk/www/cxx_dr_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?rev=363352&r1=363351&r2=363352&view=diff
==============================================================================
--- cfe/trunk/www/cxx_dr_status.html (original)
+++ cfe/trunk/www/cxx_dr_status.html Thu Jun 13 21:05:17 2019
@@ -4219,7 +4219,7 @@ and <I>POD class</I></td>
     <td><a href="http://wg21.link/cwg696">696</a></td>
     <td>C++11</td>
     <td>Use of block-scope constants in local classes</td>
-    <td class="full" align="center">Yes</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="697">
     <td><a href="http://wg21.link/cwg697">697</a></td>
@@ -4315,7 +4315,7 @@ and <I>POD class</I></td>
     <td><a href="http://wg21.link/cwg712">712</a></td>
     <td>CD3</td>
     <td>Are integer constant operands of a <I>conditional-expression</I> “used?”</td>
-    <td class="partial" align="center">Partial</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="713">
     <td><a href="http://wg21.link/cwg713">713</a></td>
@@ -12313,7 +12313,7 @@ and <I>POD class</I></td>
     <td><a href="http://wg21.link/cwg2083">2083</a></td>
     <td>DR</td>
     <td>Incorrect cases of odr-use</td>
-    <td class="partial" align="center">Partial</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2084">
     <td><a href="http://wg21.link/cwg2084">2084</a></td>
@@ -12433,7 +12433,7 @@ and <I>POD class</I></td>
     <td><a href="http://wg21.link/cwg2103">2103</a></td>
     <td>DR</td>
     <td>Lvalue-to-rvalue conversion is irrelevant in odr-use of a reference</td>
-    <td class="full" align="center">Yes</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2104">
     <td><a href="http://wg21.link/cwg2104">2104</a></td>
@@ -12655,7 +12655,7 @@ and <I>POD class</I></td>
     <td><a href="http://wg21.link/cwg2140">2140</a></td>
     <td>CD4</td>
     <td>Lvalue-to-rvalue conversion of <TT>std::nullptr_t</TT></td>
-    <td class="svn" align="center">SVN</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2141">
     <td><a href="http://wg21.link/cwg2141">2141</a></td>
@@ -12835,7 +12835,7 @@ and <I>POD class</I></td>
     <td><a href="http://wg21.link/cwg2170">2170</a></td>
     <td>DR</td>
     <td>Unclear definition of odr-use for arrays</td>
-    <td class="svn" align="center">SVN</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2171">
     <td><a href="http://wg21.link/cwg2171">2171</a></td>
@@ -13933,7 +13933,7 @@ and <I>POD class</I></td>
     <td><a href="http://wg21.link/cwg2353">2353</a></td>
     <td>DR</td>
     <td>Potential results of a member access expression for a static data member</td>
-    <td class="svn" align="center">SVN</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr id="2354">
     <td><a href="http://wg21.link/cwg2354">2354</a></td>




More information about the cfe-commits mailing list