[clang] d1751d1 - PR47175: Ensure type-dependent function-style casts have dependent
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 8 17:02:01 PDT 2020
Author: Richard Smith
Date: 2020-10-08T17:00:22-07:00
New Revision: d1751d14a6b2787974a4d203be2b554de9fa613c
URL: https://github.com/llvm/llvm-project/commit/d1751d14a6b2787974a4d203be2b554de9fa613c
DIFF: https://github.com/llvm/llvm-project/commit/d1751d14a6b2787974a4d203be2b554de9fa613c.diff
LOG: PR47175: Ensure type-dependent function-style casts have dependent
types.
Previously, a type-dependent cast to a deduced class template
specialization type would end up with a non-dependent class template
specialization type, leading to confusion downstream.
Added:
Modified:
clang/include/clang/AST/ExprCXX.h
clang/lib/AST/ASTImporter.cpp
clang/lib/AST/ComputeDependence.cpp
clang/lib/AST/ExprCXX.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
index 9658f37723e1..926021e9c6ed 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -3427,17 +3427,18 @@ class CXXUnresolvedConstructExpr final
/// The location of the right parentheses (')').
SourceLocation RParenLoc;
- CXXUnresolvedConstructExpr(TypeSourceInfo *TSI, SourceLocation LParenLoc,
- ArrayRef<Expr *> Args, SourceLocation RParenLoc);
+ CXXUnresolvedConstructExpr(QualType T, TypeSourceInfo *TSI,
+ SourceLocation LParenLoc, ArrayRef<Expr *> Args,
+ SourceLocation RParenLoc);
CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs)
- : Expr(CXXUnresolvedConstructExprClass, Empty) {
+ : Expr(CXXUnresolvedConstructExprClass, Empty), TSI(nullptr) {
CXXUnresolvedConstructExprBits.NumArgs = NumArgs;
}
public:
static CXXUnresolvedConstructExpr *Create(const ASTContext &Context,
- TypeSourceInfo *Type,
+ QualType T, TypeSourceInfo *TSI,
SourceLocation LParenLoc,
ArrayRef<Expr *> Args,
SourceLocation RParenLoc);
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 60b6a9706d6a..05cc717581ef 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -7535,6 +7535,7 @@ ExpectedStmt ASTNodeImporter::VisitCXXUnresolvedConstructExpr(
Error Err = Error::success();
auto ToLParenLoc = importChecked(Err, E->getLParenLoc());
auto ToRParenLoc = importChecked(Err, E->getRParenLoc());
+ auto ToType = importChecked(Err, E->getType());
auto ToTypeSourceInfo = importChecked(Err, E->getTypeSourceInfo());
if (Err)
return std::move(Err);
@@ -7545,7 +7546,7 @@ ExpectedStmt ASTNodeImporter::VisitCXXUnresolvedConstructExpr(
return std::move(Err);
return CXXUnresolvedConstructExpr::Create(
- Importer.getToContext(), ToTypeSourceInfo, ToLParenLoc,
+ Importer.getToContext(), ToType, ToTypeSourceInfo, ToLParenLoc,
llvm::makeArrayRef(ToArgs), ToRParenLoc);
}
diff --git a/clang/lib/AST/ComputeDependence.cpp b/clang/lib/AST/ComputeDependence.cpp
index f8dfeed0962e..d837ae29cb54 100644
--- a/clang/lib/AST/ComputeDependence.cpp
+++ b/clang/lib/AST/ComputeDependence.cpp
@@ -711,8 +711,6 @@ ExprDependence clang::computeDependence(LambdaExpr *E,
ExprDependence clang::computeDependence(CXXUnresolvedConstructExpr *E) {
auto D = ExprDependence::ValueInstantiation;
D |= toExprDependence(E->getType()->getDependence());
- if (E->getType()->getContainedDeducedType())
- D |= ExprDependence::Type;
for (auto *A : E->arguments())
D |= A->getDependence() &
(ExprDependence::UnexpandedPack | ExprDependence::Error);
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index fe2de4b8cbce..4a421f03e589 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -1316,12 +1316,12 @@ ExprWithCleanups *ExprWithCleanups::Create(const ASTContext &C,
return new (buffer) ExprWithCleanups(empty, numObjects);
}
-CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(TypeSourceInfo *TSI,
+CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(QualType T,
+ TypeSourceInfo *TSI,
SourceLocation LParenLoc,
ArrayRef<Expr *> Args,
SourceLocation RParenLoc)
- : Expr(CXXUnresolvedConstructExprClass,
- TSI->getType().getNonReferenceType(),
+ : Expr(CXXUnresolvedConstructExprClass, T,
(TSI->getType()->isLValueReferenceType()
? VK_LValue
: TSI->getType()->isRValueReferenceType() ? VK_XValue
@@ -1336,10 +1336,11 @@ CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(TypeSourceInfo *TSI,
}
CXXUnresolvedConstructExpr *CXXUnresolvedConstructExpr::Create(
- const ASTContext &Context, TypeSourceInfo *TSI, SourceLocation LParenLoc,
+ const ASTContext &Context, QualType T, TypeSourceInfo *TSI, SourceLocation LParenLoc,
ArrayRef<Expr *> Args, SourceLocation RParenLoc) {
void *Mem = Context.Allocate(totalSizeToAlloc<Expr *>(Args.size()));
- return new (Mem) CXXUnresolvedConstructExpr(TSI, LParenLoc, Args, RParenLoc);
+ return new (Mem)
+ CXXUnresolvedConstructExpr(T, TSI, LParenLoc, Args, RParenLoc);
}
CXXUnresolvedConstructExpr *
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 5f4afb38bc25..ed57772cd237 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -1413,16 +1413,6 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo,
QualType Ty = TInfo->getType();
SourceLocation TyBeginLoc = TInfo->getTypeLoc().getBeginLoc();
- if (Ty->isDependentType() || CallExpr::hasAnyTypeDependentArguments(Exprs)) {
- // FIXME: CXXUnresolvedConstructExpr does not model list-initialization
- // directly. We work around this by dropping the locations of the braces.
- SourceRange Locs = ListInitialization
- ? SourceRange()
- : SourceRange(LParenOrBraceLoc, RParenOrBraceLoc);
- return CXXUnresolvedConstructExpr::Create(Context, TInfo, Locs.getBegin(),
- Exprs, Locs.getEnd());
- }
-
assert((!ListInitialization ||
(Exprs.size() == 1 && isa<InitListExpr>(Exprs[0]))) &&
"List initialization must have initializer list as expression.");
@@ -1451,6 +1441,17 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo,
Entity = InitializedEntity::InitializeTemporary(TInfo, Ty);
}
+ if (Ty->isDependentType() || CallExpr::hasAnyTypeDependentArguments(Exprs)) {
+ // FIXME: CXXUnresolvedConstructExpr does not model list-initialization
+ // directly. We work around this by dropping the locations of the braces.
+ SourceRange Locs = ListInitialization
+ ? SourceRange()
+ : SourceRange(LParenOrBraceLoc, RParenOrBraceLoc);
+ return CXXUnresolvedConstructExpr::Create(Context, Ty.getNonReferenceType(),
+ TInfo, Locs.getBegin(), Exprs,
+ Locs.getEnd());
+ }
+
// C++ [expr.type.conv]p1:
// If the expression list is a parenthesized single expression, the type
// conversion expression is equivalent (in definedness, and if defined in
diff --git a/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
index e992c7c916f3..2412c9d4db74 100644
--- a/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
+++ b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
@@ -526,6 +526,12 @@ namespace PR45124 {
__thread b g;
}
+namespace PR47175 {
+ template<typename T> struct A { A(T); T x; };
+ template<typename T> int &&n = A(T()).x;
+ int m = n<int>;
+}
+
#else
// expected-no-diagnostics
More information about the cfe-commits
mailing list