summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2019-06-14 04:05:17 +0000
committerNico Weber <nicolasweber@gmx.de>2019-06-14 04:05:17 +0000
commit3d02b895eda08dda749a16c9499f3a11fd68793b (patch)
treeda36d6a87461e67af138453afafe5ffafd45d02b /clang/lib/Sema
parent5b4285d82ded14b5f486df39fbef6aacdfbd8659 (diff)
downloadbcm5719-llvm-3d02b895eda08dda749a16c9499f3a11fd68793b.tar.gz
bcm5719-llvm-3d02b895eda08dda749a16c9499f3a11fd68793b.zip
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." llvm-svn: 363352
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp159
-rw-r--r--clang/lib/Sema/SemaInit.cpp23
2 files changed, 51 insertions, 131 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index a561b045f9a..d444a35be86 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -635,10 +635,8 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
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(VarDecl *Var, SourceLocation Loc) {
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 rebuildPotentialResultsAsNonOdrUsed(Sema &S, Expr *E,
// 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 rebuildPotentialResultsAsNonOdrUsed(Sema &S, Expr *E,
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 rebuildPotentialResultsAsNonOdrUsed(Sema &S, Expr *E,
// -- 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 rebuildPotentialResultsAsNonOdrUsed(Sema &S, Expr *E,
// 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 rebuildPotentialResultsAsNonOdrUsed(Sema &S, Expr *E,
// 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;
}
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index d5ef5eddf3e..1a1d9347985 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -3282,6 +3282,7 @@ void InitializationSequence::Step::Destroy() {
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::AddAtomicConversionStep(QualType Ty) {
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::Perform(Sema &S,
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::Perform(Sema &S,
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_ostream &OS) const {
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
OpenPOWER on IntegriCloud