Skip to content

Commit d1751d1

Browse files
committed
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.
1 parent caedf79 commit d1751d1

File tree

6 files changed

+30
-22
lines changed

6 files changed

+30
-22
lines changed

clang/include/clang/AST/ExprCXX.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3427,17 +3427,18 @@ class CXXUnresolvedConstructExpr final
34273427
/// The location of the right parentheses (')').
34283428
SourceLocation RParenLoc;
34293429

3430-
CXXUnresolvedConstructExpr(TypeSourceInfo *TSI, SourceLocation LParenLoc,
3431-
ArrayRef<Expr *> Args, SourceLocation RParenLoc);
3430+
CXXUnresolvedConstructExpr(QualType T, TypeSourceInfo *TSI,
3431+
SourceLocation LParenLoc, ArrayRef<Expr *> Args,
3432+
SourceLocation RParenLoc);
34323433

34333434
CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs)
3434-
: Expr(CXXUnresolvedConstructExprClass, Empty) {
3435+
: Expr(CXXUnresolvedConstructExprClass, Empty), TSI(nullptr) {
34353436
CXXUnresolvedConstructExprBits.NumArgs = NumArgs;
34363437
}
34373438

34383439
public:
34393440
static CXXUnresolvedConstructExpr *Create(const ASTContext &Context,
3440-
TypeSourceInfo *Type,
3441+
QualType T, TypeSourceInfo *TSI,
34413442
SourceLocation LParenLoc,
34423443
ArrayRef<Expr *> Args,
34433444
SourceLocation RParenLoc);

clang/lib/AST/ASTImporter.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7535,6 +7535,7 @@ ExpectedStmt ASTNodeImporter::VisitCXXUnresolvedConstructExpr(
75357535
Error Err = Error::success();
75367536
auto ToLParenLoc = importChecked(Err, E->getLParenLoc());
75377537
auto ToRParenLoc = importChecked(Err, E->getRParenLoc());
7538+
auto ToType = importChecked(Err, E->getType());
75387539
auto ToTypeSourceInfo = importChecked(Err, E->getTypeSourceInfo());
75397540
if (Err)
75407541
return std::move(Err);
@@ -7545,7 +7546,7 @@ ExpectedStmt ASTNodeImporter::VisitCXXUnresolvedConstructExpr(
75457546
return std::move(Err);
75467547

75477548
return CXXUnresolvedConstructExpr::Create(
7548-
Importer.getToContext(), ToTypeSourceInfo, ToLParenLoc,
7549+
Importer.getToContext(), ToType, ToTypeSourceInfo, ToLParenLoc,
75497550
llvm::makeArrayRef(ToArgs), ToRParenLoc);
75507551
}
75517552

clang/lib/AST/ComputeDependence.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -711,8 +711,6 @@ ExprDependence clang::computeDependence(LambdaExpr *E,
711711
ExprDependence clang::computeDependence(CXXUnresolvedConstructExpr *E) {
712712
auto D = ExprDependence::ValueInstantiation;
713713
D |= toExprDependence(E->getType()->getDependence());
714-
if (E->getType()->getContainedDeducedType())
715-
D |= ExprDependence::Type;
716714
for (auto *A : E->arguments())
717715
D |= A->getDependence() &
718716
(ExprDependence::UnexpandedPack | ExprDependence::Error);

clang/lib/AST/ExprCXX.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,12 +1316,12 @@ ExprWithCleanups *ExprWithCleanups::Create(const ASTContext &C,
13161316
return new (buffer) ExprWithCleanups(empty, numObjects);
13171317
}
13181318

1319-
CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(TypeSourceInfo *TSI,
1319+
CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(QualType T,
1320+
TypeSourceInfo *TSI,
13201321
SourceLocation LParenLoc,
13211322
ArrayRef<Expr *> Args,
13221323
SourceLocation RParenLoc)
1323-
: Expr(CXXUnresolvedConstructExprClass,
1324-
TSI->getType().getNonReferenceType(),
1324+
: Expr(CXXUnresolvedConstructExprClass, T,
13251325
(TSI->getType()->isLValueReferenceType()
13261326
? VK_LValue
13271327
: TSI->getType()->isRValueReferenceType() ? VK_XValue
@@ -1336,10 +1336,11 @@ CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(TypeSourceInfo *TSI,
13361336
}
13371337

13381338
CXXUnresolvedConstructExpr *CXXUnresolvedConstructExpr::Create(
1339-
const ASTContext &Context, TypeSourceInfo *TSI, SourceLocation LParenLoc,
1339+
const ASTContext &Context, QualType T, TypeSourceInfo *TSI, SourceLocation LParenLoc,
13401340
ArrayRef<Expr *> Args, SourceLocation RParenLoc) {
13411341
void *Mem = Context.Allocate(totalSizeToAlloc<Expr *>(Args.size()));
1342-
return new (Mem) CXXUnresolvedConstructExpr(TSI, LParenLoc, Args, RParenLoc);
1342+
return new (Mem)
1343+
CXXUnresolvedConstructExpr(T, TSI, LParenLoc, Args, RParenLoc);
13431344
}
13441345

13451346
CXXUnresolvedConstructExpr *

clang/lib/Sema/SemaExprCXX.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,16 +1413,6 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo,
14131413
QualType Ty = TInfo->getType();
14141414
SourceLocation TyBeginLoc = TInfo->getTypeLoc().getBeginLoc();
14151415

1416-
if (Ty->isDependentType() || CallExpr::hasAnyTypeDependentArguments(Exprs)) {
1417-
// FIXME: CXXUnresolvedConstructExpr does not model list-initialization
1418-
// directly. We work around this by dropping the locations of the braces.
1419-
SourceRange Locs = ListInitialization
1420-
? SourceRange()
1421-
: SourceRange(LParenOrBraceLoc, RParenOrBraceLoc);
1422-
return CXXUnresolvedConstructExpr::Create(Context, TInfo, Locs.getBegin(),
1423-
Exprs, Locs.getEnd());
1424-
}
1425-
14261416
assert((!ListInitialization ||
14271417
(Exprs.size() == 1 && isa<InitListExpr>(Exprs[0]))) &&
14281418
"List initialization must have initializer list as expression.");
@@ -1451,6 +1441,17 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo,
14511441
Entity = InitializedEntity::InitializeTemporary(TInfo, Ty);
14521442
}
14531443

1444+
if (Ty->isDependentType() || CallExpr::hasAnyTypeDependentArguments(Exprs)) {
1445+
// FIXME: CXXUnresolvedConstructExpr does not model list-initialization
1446+
// directly. We work around this by dropping the locations of the braces.
1447+
SourceRange Locs = ListInitialization
1448+
? SourceRange()
1449+
: SourceRange(LParenOrBraceLoc, RParenOrBraceLoc);
1450+
return CXXUnresolvedConstructExpr::Create(Context, Ty.getNonReferenceType(),
1451+
TInfo, Locs.getBegin(), Exprs,
1452+
Locs.getEnd());
1453+
}
1454+
14541455
// C++ [expr.type.conv]p1:
14551456
// If the expression list is a parenthesized single expression, the type
14561457
// conversion expression is equivalent (in definedness, and if defined in

clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,12 @@ namespace PR45124 {
526526
__thread b g;
527527
}
528528

529+
namespace PR47175 {
530+
template<typename T> struct A { A(T); T x; };
531+
template<typename T> int &&n = A(T()).x;
532+
int m = n<int>;
533+
}
534+
529535
#else
530536

531537
// expected-no-diagnostics

0 commit comments

Comments
 (0)