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