diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1483,13 +1483,14 @@ // Otherwise, if the type contains a placeholder type, it is replaced by the // type determined by placeholder type deduction. DeducedType *Deduced = Ty->getContainedDeducedType(); - if (Deduced && isa(Deduced)) { + if (Deduced && !Deduced->isDeduced() && + isa(Deduced)) { Ty = DeduceTemplateSpecializationFromInitializer(TInfo, Entity, Kind, Exprs); if (Ty.isNull()) return ExprError(); Entity = InitializedEntity::InitializeTemporary(TInfo, Ty); - } else if (Deduced) { + } else if (Deduced && !Deduced->isDeduced()) { MultiExprArg Inits = Exprs; if (ListInitialization) { auto *ILE = cast(Exprs[0]); @@ -2016,7 +2017,8 @@ // C++11 [dcl.spec.auto]p6. Deduce the type which 'auto' stands in for. auto *Deduced = AllocType->getContainedDeducedType(); - if (Deduced && isa(Deduced)) { + if (Deduced && !Deduced->isDeduced() && + isa(Deduced)) { if (ArraySize) return ExprError( Diag(*ArraySize ? (*ArraySize)->getExprLoc() : TypeRange.getBegin(), @@ -2030,7 +2032,7 @@ AllocTypeInfo, Entity, Kind, Exprs); if (AllocType.isNull()) return ExprError(); - } else if (Deduced) { + } else if (Deduced && !Deduced->isDeduced()) { MultiExprArg Inits = Exprs; bool Braced = (initStyle == CXXNewExpr::ListInit); if (Braced) { diff --git a/clang/test/SemaTemplate/sugar-crashes.cpp b/clang/test/SemaTemplate/sugar-crashes.cpp new file mode 100644 --- /dev/null +++ b/clang/test/SemaTemplate/sugar-crashes.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -verify %s +// expected-no-diagnostics + + +struct StringPiece { + template + StringPiece(T str) {} +}; + +void f(StringPiece utf8) {} + +struct S { +}; + +void G() { + const auto s = S{}; + StringPiece U{s}; +} +