aboutsummaryrefslogtreecommitdiff
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/docs/ReleaseNotes.rst6
-rw-r--r--clang/include/clang/Sema/SemaConcept.h2
-rw-r--r--clang/lib/AST/ByteCode/InterpBuiltin.cpp4
-rw-r--r--clang/lib/AST/DeclPrinter.cpp4
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp6
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp7
-rw-r--r--clang/lib/Sema/SemaChecking.cpp3
-rw-r--r--clang/lib/Sema/SemaConcept.cpp29
-rw-r--r--clang/lib/Sema/SemaInit.cpp6
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp13
-rw-r--r--clang/lib/Sema/SemaTemplateDeduction.cpp4
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp6
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp18
-rw-r--r--clang/test/AST/ast-print-record-decl.c13
-rw-r--r--clang/test/CIR/CodeGen/struct.cpp33
-rw-r--r--clang/test/Parser/cxx0x-lambda-expressions.cpp2
-rw-r--r--clang/test/SemaCXX/builtin-assume-aligned.cpp13
-rw-r--r--clang/test/SemaCXX/diagnose_if.cpp27
-rw-r--r--clang/test/SemaCXX/lambda-expressions.cpp30
-rw-r--r--clang/test/SemaTemplate/alias-template-deprecated.cpp17
-rw-r--r--clang/test/SemaTemplate/alias-templates.cpp8
-rw-r--r--clang/test/SemaTemplate/concepts.cpp71
22 files changed, 266 insertions, 56 deletions
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index d2e5bd2..05379f4 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -123,6 +123,9 @@ AST Dumping Potentially Breaking Changes
``__atomic_test_and_set(p, 0)``
+- Pretty-printing of templates with inherited (i.e. specified in a previous
+ redeclaration) default arguments has been fixed.
+
Clang Frontend Potentially Breaking Changes
-------------------------------------------
- Members of anonymous unions/structs are now injected as ``IndirectFieldDecl``
@@ -250,6 +253,8 @@ Non-comprehensive list of changes in this release
- ``__builtin_assume_dereferenceable`` now accepts non-constant size operands.
+- Fixed a crash when the second argument to ``__builtin_assume_aligned`` was not constant (#GH161314)
+
New Compiler Flags
------------------
- New option ``-fno-sanitize-debug-trap-reasons`` added to disable emitting trap reasons into the debug info when compiling with trapping UBSan (e.g. ``-fsanitize-trap=undefined``).
@@ -452,6 +457,7 @@ Bug Fixes to AST Handling
Miscellaneous Bug Fixes
^^^^^^^^^^^^^^^^^^^^^^^
+- Fixed missing diagnostics of ``diagnose_if`` on templates involved in initialization. (#GH160776)
Miscellaneous Clang Crashes Fixed
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/Sema/SemaConcept.h b/clang/include/clang/Sema/SemaConcept.h
index 51ca1e1..bdd997b 100644
--- a/clang/include/clang/Sema/SemaConcept.h
+++ b/clang/include/clang/Sema/SemaConcept.h
@@ -257,6 +257,7 @@ public:
case ConstraintKind::FoldExpanded:
return FoldExpanded.Pattern->getBeginLoc();
}
+ llvm_unreachable("Unknown ConstraintKind enum");
}
SourceLocation getEndLoc() const {
@@ -270,6 +271,7 @@ public:
case ConstraintKind::FoldExpanded:
return FoldExpanded.Pattern->getEndLoc();
}
+ llvm_unreachable("Unknown ConstraintKind enum");
}
SourceRange getSourceRange() const { return {getBeginLoc(), getEndLoc()}; }
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 6053237..68ebfdf 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -2796,7 +2796,7 @@ static bool interp__builtin_ia32_pshuf(InterpState &S, CodePtr OpPC,
unsigned LaneBase = (Idx / LaneElts) * LaneElts;
unsigned LaneIdx = Idx % LaneElts;
unsigned SrcIdx = Idx;
- unsigned Sel = (Ctl >> (2 * LaneIdx)) & 0x3;
+ unsigned Sel = (Ctl >> (2 * (LaneIdx & 0x3))) & 0x3;
if (ElemBits == 32) {
SrcIdx = LaneBase + Sel;
} else {
@@ -2805,8 +2805,6 @@ static bool interp__builtin_ia32_pshuf(InterpState &S, CodePtr OpPC,
if (!IsShufHW && !InHigh) {
SrcIdx = LaneBase + Sel;
} else if (IsShufHW && InHigh) {
- unsigned Rel = LaneIdx - HalfSize;
- Sel = (Ctl >> (2 * Rel)) & 0x3;
SrcIdx = LaneBase + HalfSize + Sel;
}
}
diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp
index 196057f..7001ade 100644
--- a/clang/lib/AST/DeclPrinter.cpp
+++ b/clang/lib/AST/DeclPrinter.cpp
@@ -1894,7 +1894,7 @@ void DeclPrinter::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *TTP) {
Out << TTP->getDeclName();
}
- if (TTP->hasDefaultArgument()) {
+ if (TTP->hasDefaultArgument() && !TTP->defaultArgumentWasInherited()) {
Out << " = ";
TTP->getDefaultArgument().getArgument().print(Policy, Out,
/*IncludeType=*/false);
@@ -1909,7 +1909,7 @@ void DeclPrinter::VisitNonTypeTemplateParmDecl(
Policy.CleanUglifiedParameters ? II->deuglifiedName() : II->getName();
printDeclType(NTTP->getType(), Name, NTTP->isParameterPack());
- if (NTTP->hasDefaultArgument()) {
+ if (NTTP->hasDefaultArgument() && !NTTP->defaultArgumentWasInherited()) {
Out << " = ";
NTTP->getDefaultArgument().getArgument().print(Policy, Out,
/*IncludeType=*/false);
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
index e51c3fc..60ccf18 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
@@ -201,8 +201,10 @@ public:
}
void VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *e) {
- cgf.cgm.errorNYI(e->getSourceRange(),
- "AggExprEmitter: VisitDesignatedInitUpdateExpr");
+ AggValueSlot dest = ensureSlot(cgf.getLoc(e->getExprLoc()), e->getType());
+ LValue destLV = cgf.makeAddrLValue(dest.getAddress(), e->getType());
+ emitInitializationToLValue(e->getBase(), destLV);
+ VisitInitListExpr(e->getUpdater());
}
void VisitAbstractConditionalOperator(const AbstractConditionalOperator *e) {
cgf.cgm.errorNYI(e->getSourceRange(),
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index f319b17..c961222 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -465,11 +465,16 @@ public:
return nullptr;
if (Value *Result = ConstantEmitter(CGF).tryEmitConstantExpr(E)) {
- if (E->isGLValue())
+ if (E->isGLValue()) {
+ // This was already converted to an rvalue when it was constant
+ // evaluated.
+ if (E->hasAPValueResult() && !E->getAPValueResult().isLValue())
+ return Result;
return CGF.EmitLoadOfScalar(
Address(Result, CGF.convertTypeForLoadStore(E->getType()),
CGF.getContext().getTypeAlignInChars(E->getType())),
/*Volatile*/ false, E->getType(), E->getExprLoc());
+ }
return Result;
}
return Visit(E->getSubExpr());
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 7ce3513..3cc61b1 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -5954,6 +5954,9 @@ bool Sema::BuiltinAssumeAligned(CallExpr *TheCall) {
if (Result > Sema::MaximumAlignment)
Diag(TheCall->getBeginLoc(), diag::warn_assume_aligned_too_great)
<< SecondArg->getSourceRange() << Sema::MaximumAlignment;
+
+ TheCall->setArg(1,
+ ConstantExpr::Create(Context, SecondArg, APValue(Result)));
}
if (NumArgs > 2) {
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 8413090..11d2d5c 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -264,14 +264,6 @@ class HashParameterMapping : public RecursiveASTVisitor<HashParameterMapping> {
UnsignedOrNone OuterPackSubstIndex;
- TemplateArgument getPackSubstitutedTemplateArgument(TemplateArgument Arg) {
- assert(*SemaRef.ArgPackSubstIndex < Arg.pack_size());
- Arg = Arg.pack_begin()[*SemaRef.ArgPackSubstIndex];
- if (Arg.isPackExpansion())
- Arg = Arg.getPackExpansionPattern();
- return Arg;
- }
-
bool shouldVisitTemplateInstantiations() const { return true; }
public:
@@ -294,7 +286,7 @@ public:
assert(Arg.getKind() == TemplateArgument::Pack &&
"Missing argument pack");
- Arg = getPackSubstitutedTemplateArgument(Arg);
+ Arg = SemaRef.getPackSubstitutedTemplateArgument(Arg);
}
UsedTemplateArgs.push_back(
@@ -312,7 +304,7 @@ public:
if (NTTP->isParameterPack() && SemaRef.ArgPackSubstIndex) {
assert(Arg.getKind() == TemplateArgument::Pack &&
"Missing argument pack");
- Arg = getPackSubstitutedTemplateArgument(Arg);
+ Arg = SemaRef.getPackSubstitutedTemplateArgument(Arg);
}
UsedTemplateArgs.push_back(
@@ -325,8 +317,11 @@ public:
}
bool TraverseDecl(Decl *D) {
- if (auto *VD = dyn_cast<ValueDecl>(D))
+ if (auto *VD = dyn_cast<ValueDecl>(D)) {
+ if (auto *Var = dyn_cast<VarDecl>(VD))
+ TraverseStmt(Var->getInit());
return TraverseType(VD->getType());
+ }
return inherited::TraverseDecl(D);
}
@@ -363,6 +358,14 @@ public:
return inherited::TraverseTemplateArgument(Arg);
}
+ bool TraverseSizeOfPackExpr(SizeOfPackExpr *SOPE) {
+ return TraverseDecl(SOPE->getPack());
+ }
+
+ bool VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E) {
+ return inherited::TraverseStmt(E->getReplacement());
+ }
+
void VisitConstraint(const NormalizedConstraintWithParamMapping &Constraint) {
if (!Constraint.hasParameterMapping()) {
for (const auto &List : TemplateArgs)
@@ -2083,8 +2086,8 @@ bool SubstituteParameterMappings::substitute(ConceptIdConstraint &CC) {
/*UpdateArgsWithConversions=*/false))
return true;
auto TemplateArgs = *MLTAL;
- TemplateArgs.replaceOutermostTemplateArguments(
- TemplateArgs.getAssociatedDecl(0).first, CTAI.SugaredConverted);
+ TemplateArgs.replaceOutermostTemplateArguments(CSE->getNamedConcept(),
+ CTAI.SugaredConverted);
return SubstituteParameterMappings(SemaRef, &TemplateArgs, ArgsAsWritten,
InFoldExpr)
.substitute(CC.getNormalizedConstraint());
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 0d0d2c0..922fcac 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -7539,7 +7539,7 @@ PerformConstructorInitialization(Sema &S,
// Only check access if all of that succeeded.
S.CheckConstructorAccess(Loc, Constructor, Step.Function.FoundDecl, Entity);
- if (S.DiagnoseUseOfDecl(Step.Function.FoundDecl, Loc))
+ if (S.DiagnoseUseOfOverloadedDecl(Constructor, Loc))
return ExprError();
if (const ArrayType *AT = S.Context.getAsArrayType(Entity.getType()))
@@ -8092,7 +8092,7 @@ ExprResult InitializationSequence::Perform(Sema &S,
S.CheckConstructorAccess(Kind.getLocation(), Constructor, FoundFn,
Entity);
- if (S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation()))
+ if (S.DiagnoseUseOfOverloadedDecl(Constructor, Kind.getLocation()))
return ExprError();
CastKind = CK_ConstructorConversion;
@@ -8102,7 +8102,7 @@ ExprResult InitializationSequence::Perform(Sema &S,
CXXConversionDecl *Conversion = cast<CXXConversionDecl>(Fn);
S.CheckMemberOperatorAccess(Kind.getLocation(), CurInit.get(), nullptr,
FoundFn);
- if (S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation()))
+ if (S.DiagnoseUseOfOverloadedDecl(Conversion, Kind.getLocation()))
return ExprError();
CurInit = S.BuildCXXMemberCallExpr(CurInit.get(), FoundFn, Conversion,
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index dcf2876..419f3e1 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -3822,14 +3822,19 @@ QualType Sema::CheckTemplateIdType(ElaboratedTypeKeyword Keyword,
AliasTemplate->getTemplateParameters()->getDepth());
LocalInstantiationScope Scope(*this);
- InstantiatingTemplate Inst(
- *this, /*PointOfInstantiation=*/TemplateLoc,
- /*Entity=*/AliasTemplate,
- /*TemplateArgs=*/TemplateArgLists.getInnermost());
// Diagnose uses of this alias.
(void)DiagnoseUseOfDecl(AliasTemplate, TemplateLoc);
+ // FIXME: The TemplateArgs passed here are not used for the context note,
+ // nor they should, because this note will be pointing to the specialization
+ // anyway. These arguments are needed for a hack for instantiating lambdas
+ // in the pattern of the alias. In getTemplateInstantiationArgs, these
+ // arguments will be used for collating the template arguments needed to
+ // instantiate the lambda.
+ InstantiatingTemplate Inst(*this, /*PointOfInstantiation=*/TemplateLoc,
+ /*Entity=*/AliasTemplate,
+ /*TemplateArgs=*/CTAI.SugaredConverted);
if (Inst.isInvalid())
return QualType();
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 6bba505..3baa977 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -6718,6 +6718,10 @@ struct MarkUsedTemplateParameterVisitor : DynamicRecursiveASTVisitor {
}
return true;
}
+
+ bool TraverseSizeOfPackExpr(SizeOfPackExpr *SOPE) override {
+ return TraverseDecl(SOPE->getPack());
+ }
};
}
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 1f762ca..7b05e4c 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1271,6 +1271,12 @@ void Sema::PrintInstantiationStack(InstantiationContextDiagFuncRef DiagFunc) {
PDiag(diag::note_building_deduction_guide_here));
break;
case CodeSynthesisContext::TypeAliasTemplateInstantiation:
+ // Workaround for a workaround: don't produce a note if we are merely
+ // instantiating some other template which contains this alias template.
+ // This would be redundant either with the error itself, or some other
+ // context note attached to it.
+ if (Active->NumTemplateArgs == 0)
+ break;
DiagFunc(Active->PointOfInstantiation,
PDiag(diag::note_template_type_alias_instantiation_here)
<< cast<TypeAliasTemplateDecl>(Active->Entity)
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index e2dc703..3819f77 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1580,17 +1580,19 @@ Decl *TemplateDeclInstantiator::InstantiateTypeAliasTemplateDecl(
if (!InstParams)
return nullptr;
- TypeAliasDecl *Pattern = D->getTemplatedDecl();
- Sema::InstantiatingTemplate InstTemplate(
- SemaRef, D->getBeginLoc(), D,
- D->getTemplateDepth() >= TemplateArgs.getNumLevels()
- ? ArrayRef<TemplateArgument>()
- : (TemplateArgs.begin() + TemplateArgs.getNumLevels() - 1 -
- D->getTemplateDepth())
- ->Args);
+ // FIXME: This is a hack for instantiating lambdas in the pattern of the
+ // alias. We are not really instantiating the alias at its template level,
+ // that only happens in CheckTemplateId, this is only for outer templates
+ // which contain it. In getTemplateInstantiationArgs, the template arguments
+ // used here would be used for collating the template arguments needed to
+ // instantiate the lambda. Pass an empty argument list, so this workaround
+ // doesn't get confused if there is an outer alias being instantiated.
+ Sema::InstantiatingTemplate InstTemplate(SemaRef, D->getBeginLoc(), D,
+ ArrayRef<TemplateArgument>());
if (InstTemplate.isInvalid())
return nullptr;
+ TypeAliasDecl *Pattern = D->getTemplatedDecl();
TypeAliasTemplateDecl *PrevAliasTemplate = nullptr;
if (getPreviousDeclForInstantiation<TypedefNameDecl>(Pattern)) {
DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName());
diff --git a/clang/test/AST/ast-print-record-decl.c b/clang/test/AST/ast-print-record-decl.c
index d3717a4..fd81588 100644
--- a/clang/test/AST/ast-print-record-decl.c
+++ b/clang/test/AST/ast-print-record-decl.c
@@ -290,9 +290,9 @@ KW DeclGroupInMemberList {
// A tag decl group in the tag decl's own member list is exercised in
// defSelfRef above.
+#ifdef __cplusplus
// Check out-of-line record definition
-#ifdef __cplusplus
// PRINT-CXX-NEXT: [[KW]] OutOfLineRecord {
KW OutOfLineRecord {
// PRINT-CXX-NEXT: [[KW]] Inner
@@ -304,4 +304,15 @@ KW OutOfLineRecord {
KW OutOfLineRecord::Inner {
// PRINT-CXX-NEXT: };
};
+
+// PRINT-CXX-NEXT: template <typename, typename = int> [[KW]] SmearedTypeDefArgs;
+template <typename, typename = int> KW SmearedTypeDefArgs;
+// PRINT-CXX-NEXT: template <typename = int, typename> [[KW]] SmearedTypeDefArgs;
+template <typename = int, typename> KW SmearedTypeDefArgs;
+
+// PRINT-CXX-NEXT: template <int, int = 0> [[KW]] SmearedNTTPDefArgs;
+template <int, int = 0> KW SmearedNTTPDefArgs;
+// PRINT-CXX-NEXT: template <int = 0, int> [[KW]] SmearedNTTPDefArgs;
+template <int = 0, int> KW SmearedNTTPDefArgs;
+
#endif
diff --git a/clang/test/CIR/CodeGen/struct.cpp b/clang/test/CIR/CodeGen/struct.cpp
index c68f742..263799f 100644
--- a/clang/test/CIR/CodeGen/struct.cpp
+++ b/clang/test/CIR/CodeGen/struct.cpp
@@ -184,6 +184,39 @@ void generic_selection() {
// OGCG: %[[D_ADDR:.*]] = alloca %struct.CompleteS, align 4
// OGCG: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[D_ADDR]], ptr align 4 %[[A_ADDR]], i64 8, i1 false)
+void designated_init_update_expr() {
+ CompleteS a;
+
+ struct Container {
+ CompleteS c;
+ } b = {a, .c.a = 1};
+}
+
+// CIR: %[[A_ADDR:.*]] = cir.alloca !rec_CompleteS, !cir.ptr<!rec_CompleteS>, ["a"]
+// CIR: %[[B_ADDR:.*]] = cir.alloca !rec_Container, !cir.ptr<!rec_Container>, ["b", init]
+// CIR: %[[C_ADDR:.*]] = cir.get_member %[[B_ADDR]][0] {name = "c"} : !cir.ptr<!rec_Container> -> !cir.ptr<!rec_CompleteS>
+// CIR: cir.call @_ZN9CompleteSC1ERKS_(%2, %[[A_ADDR]]) nothrow : (!cir.ptr<!rec_CompleteS>, !cir.ptr<!rec_CompleteS>) -> ()
+// CIR: %[[ELEM_0_PTR:.*]] = cir.get_member %[[C_ADDR]][0] {name = "a"} : !cir.ptr<!rec_CompleteS> -> !cir.ptr<!s32i>
+// CIR: %[[CONST_1:.*]] = cir.const #cir.int<1> : !s32i
+// CIR: cir.store{{.*}} %[[CONST_1]], %[[ELEM_0_PTR]] : !s32i, !cir.ptr<!s32i>
+// CIR: %[[ELEM_1_PTR:.*]] = cir.get_member %[[C_ADDR]][1] {name = "b"} : !cir.ptr<!rec_CompleteS> -> !cir.ptr<!s8i>
+
+// LLVM: %[[A_ADDR:.*]] = alloca %struct.CompleteS, i64 1, align 4
+// LLVM: %[[B_ADDR:.*]] = alloca %struct.Container, i64 1, align 4
+// LLVM: %[[C_ADDR:.*]] = getelementptr %struct.Container, ptr %[[B_ADDR]], i32 0, i32 0
+// LLVM: call void @_ZN9CompleteSC1ERKS_(ptr %[[C_ADDR]], ptr %[[A_ADDR]])
+// LLVM: %[[ELEM_0_PTR:.*]] = getelementptr %struct.CompleteS, ptr %[[C_ADDR]], i32 0, i32 0
+// LLVM: store i32 1, ptr %[[ELEM_0_PTR]], align 4
+// LLVM: %[[ELEM_1_PTR:.*]] = getelementptr %struct.CompleteS, ptr %[[C_ADDR]], i32 0, i32 1
+
+// OGCG: %[[A_ADDR:.*]] = alloca %struct.CompleteS, align 4
+// OGCG: %[[B_ADDR:.*]] = alloca %struct.Container, align 4
+// OGCG: %[[C_ADDR:.*]] = getelementptr inbounds nuw %struct.Container, ptr %[[B_ADDR]], i32 0, i32 0
+// OGCG: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[C_ADDR]], ptr align 4 %[[A_ADDR]], i64 8, i1 false)
+// OGCG: %[[ELEM_0_PTR:.*]] = getelementptr inbounds nuw %struct.CompleteS, ptr %[[C_ADDR]], i32 0, i32 0
+// OGCG: store i32 1, ptr %[[ELEM_0_PTR]], align 4
+// OGCG: %[[ELEM_1_PTR:.*]] = getelementptr inbounds nuw %struct.CompleteS, ptr %[[C_ADDR]], i32 0, i32 1
+
void atomic_init() {
_Atomic CompleteS a;
__c11_atomic_init(&a, {});
diff --git a/clang/test/Parser/cxx0x-lambda-expressions.cpp b/clang/test/Parser/cxx0x-lambda-expressions.cpp
index f90f8ce..5b57c7f 100644
--- a/clang/test/Parser/cxx0x-lambda-expressions.cpp
+++ b/clang/test/Parser/cxx0x-lambda-expressions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify=expected,cxx14ext,cxx17ext,cxx20ext,cxx23ext -std=c++03 -Wno-c99-designator %s -Wno-c++11-extensions
+// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify=expected,cxx14ext,cxx17ext,cxx20ext,cxx23ext -std=c++03 -Wno-c99-designator %s -Wno-c++11-extensions -Wno-local-type-template-args
// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify=expected,cxx14ext,cxx17ext,cxx20ext,cxx23ext -std=c++11 -Wno-c99-designator %s
// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify=expected,cxx17ext,cxx20ext,cxx23ext -std=c++14 -Wno-c99-designator %s
// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify=expected,cxx20ext,cxx23ext -std=c++17 -Wno-c99-designator %s
diff --git a/clang/test/SemaCXX/builtin-assume-aligned.cpp b/clang/test/SemaCXX/builtin-assume-aligned.cpp
index 48bd841..30296c7 100644
--- a/clang/test/SemaCXX/builtin-assume-aligned.cpp
+++ b/clang/test/SemaCXX/builtin-assume-aligned.cpp
@@ -47,3 +47,16 @@ constexpr void *s1 = __builtin_assume_aligned(x, 32);
constexpr void *s2 = __builtin_assume_aligned(x, 32, 5);
constexpr void *s3 = __builtin_assume_aligned(x, 32, -1);
+
+constexpr int add(int a, int b) {
+ return a+b;
+}
+constexpr void *c1 = __builtin_assume_aligned(p, add(1,1));
+constexpr void *c2 = __builtin_assume_aligned(p, add(2,1)); // expected-error {{not a power of 2}}
+
+constexpr long kAlignment = 128;
+long AllocateAlignedBytes_payload;
+void AllocateAlignedBytes() {
+ void *m = __builtin_assume_aligned(
+ reinterpret_cast<void *>(AllocateAlignedBytes_payload), kAlignment);
+}
diff --git a/clang/test/SemaCXX/diagnose_if.cpp b/clang/test/SemaCXX/diagnose_if.cpp
index 1b9e660..0af8bb7 100644
--- a/clang/test/SemaCXX/diagnose_if.cpp
+++ b/clang/test/SemaCXX/diagnose_if.cpp
@@ -1,5 +1,7 @@
// RUN: %clang_cc1 %s -verify -fno-builtin -std=c++14
+// RUN: %clang_cc1 %s -verify -fno-builtin -std=c++20 -verify=expected,cxx20
// RUN: %clang_cc1 %s -verify -fno-builtin -std=c++14 -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 %s -verify -fno-builtin -std=c++20 -verify=expected,cxx20 -fexperimental-new-constant-interpreter
#define _diagnose_if(...) __attribute__((diagnose_if(__VA_ARGS__)))
@@ -665,3 +667,28 @@ void run() {
switch (constexpr Foo i = 2) { default: break; } // expected-error{{oh no}}
}
}
+
+namespace GH160776 {
+
+struct ConstructorTemplate {
+ template <class T>
+ explicit ConstructorTemplate(T x)
+ _diagnose_if(sizeof(T) == sizeof(char), "oh no", "error") {} // expected-note {{diagnose_if}}
+
+ template <class T>
+#if __cplusplus >= 202002L
+ requires (sizeof(T) == 1) // cxx20-note {{evaluated to false}}
+#endif
+ operator T() _diagnose_if(sizeof(T) == sizeof(char), "oh no", "error") { // expected-note {{diagnose_if}} \
+ // cxx20-note {{constraints not satisfied}}
+ return T{};
+ }
+};
+
+void run() {
+ ConstructorTemplate x('1'); // expected-error {{oh no}}
+ char y = x; // expected-error {{oh no}}
+ int z = x; // cxx20-error {{no viable conversion}}
+}
+
+}
diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp
index 8ea8e32..f9d7cfc 100644
--- a/clang/test/SemaCXX/lambda-expressions.cpp
+++ b/clang/test/SemaCXX/lambda-expressions.cpp
@@ -149,7 +149,8 @@ namespace PR12031 {
void f(int i, X x);
void g() {
const int v = 10;
- f(v, [](){});
+ f(v, [](){}); // cxx03-warning {{template argument uses local type}} \
+ // cxx03-note {{while substituting}}
}
}
@@ -572,26 +573,37 @@ namespace PR27994 {
struct A { template <class T> A(T); };
template <class T>
-struct B {
+struct B { // #PR27994_B
int x;
- A a = [&] { int y = x; };
- A b = [&] { [&] { [&] { int y = x; }; }; };
- A d = [&](auto param) { int y = x; }; // cxx03-cxx11-error {{'auto' not allowed in lambda parameter}}
- A e = [&](auto param) { [&] { [&](auto param2) { int y = x; }; }; }; // cxx03-cxx11-error 2 {{'auto' not allowed in lambda parameter}}
+ A a = [&] { int y = x; }; // cxx03-warning {{template argument uses unnamed type}} \
+ // cxx03-note {{while substituting}} cxx03-note {{unnamed type used}}
+ A b = [&] { [&] { [&] { int y = x; }; }; }; // cxx03-warning {{template argument uses unnamed type}} \
+ // cxx03-note {{while substituting}} cxx03-note {{unnamed type used}}
+ A d = [&](auto param) { int y = x; }; // cxx03-cxx11-error {{'auto' not allowed in lambda parameter}} \
+ // cxx03-warning {{template argument uses unnamed type}} \
+ // cxx03-note {{while substituting}} cxx03-note {{unnamed type used}}
+ A e = [&](auto param) { [&] { [&](auto param2) { int y = x; }; }; }; // cxx03-cxx11-error 2 {{'auto' not allowed in lambda parameter}} \
+ // cxx03-warning {{template argument uses unnamed type}} \
+ // cxx03-note {{while substituting}} cxx03-note {{unnamed type used}}
};
B<int> b;
+// cxx03-note@#PR27994_B 4{{in instantiation of default member initializer}}
+// cxx03-note@-2 4{{in evaluation of exception}}
template <class T> struct C {
struct D {
+ // cxx03-note@-1 {{in instantiation of default member initializer}}
int x;
- A f = [&] { int y = x; };
+ A f = [&] { int y = x; }; // cxx03-warning {{template argument uses unnamed type}} \
+ // cxx03-note {{while substituting}} cxx03-note {{unnamed type used}}
};
};
int func() {
C<int> a;
decltype(a)::D b;
+ // cxx03-note@-1 {{in evaluation of exception}}
}
}
@@ -606,8 +618,12 @@ struct S1 {
void foo1() {
auto s0 = S1([name=]() {}); // expected-error {{expected expression}}
+ // cxx03-warning@-1 {{template argument uses local type}} \
+ // cxx03-note@-1 {{while substituting deduced template arguments}}
auto s1 = S1([name=name]() {}); // expected-error {{use of undeclared identifier 'name'; did you mean 'name1'?}}
// cxx03-cxx11-warning@-1 {{initialized lambda captures are a C++14 extension}}
+ // cxx03-warning@-2 {{template argument uses local type}} \
+ // cxx03-note@-2 {{while substituting deduced template arguments}}
}
}
diff --git a/clang/test/SemaTemplate/alias-template-deprecated.cpp b/clang/test/SemaTemplate/alias-template-deprecated.cpp
index 7418e222..6dffd37 100644
--- a/clang/test/SemaTemplate/alias-template-deprecated.cpp
+++ b/clang/test/SemaTemplate/alias-template-deprecated.cpp
@@ -46,23 +46,19 @@ using UsingInstWithCPPAttr [[deprecated("Do not use this")]] = NoAttr<int>;
void bar() {
NoAttr<int> obj; // Okay
- // expected-warning@+2 {{'UsingWithAttr' is deprecated}}
- // expected-note@+1 {{in instantiation of template type alias 'UsingWithAttr' requested here}}
+ // expected-warning@+1 {{'UsingWithAttr' is deprecated}}
UsingWithAttr<int> objUsingWA;
- // expected-warning@+2 {{'UsingWithAttr' is deprecated}}
- // expected-note@+1 {{in instantiation of template type alias 'UsingWithAttr' requested here}}
+ // expected-warning@+1 {{'UsingWithAttr' is deprecated}}
NoAttr<UsingWithAttr<int>> s;
// expected-note@+1 {{'DepInt' has been explicitly marked deprecated here}}
using DepInt [[deprecated]] = int;
- // expected-warning@+3 {{'UsingWithAttr' is deprecated}}
- // expected-warning@+2 {{'DepInt' is deprecated}}
- // expected-note@+1 {{in instantiation of template type alias 'UsingWithAttr' requested here}}
+ // expected-warning@+2 {{'UsingWithAttr' is deprecated}}
+ // expected-warning@+1 {{'DepInt' is deprecated}}
using X = UsingWithAttr<DepInt>;
- // expected-warning@+2 {{'UsingWithAttr' is deprecated}}
- // expected-note@+1 {{in instantiation of template type alias 'UsingWithAttr' requested here}}
+ // expected-warning@+1 {{'UsingWithAttr' is deprecated}}
UsingWithAttr<int>().foo();
// expected-warning@+1 {{'UsingInstWithAttr' is deprecated}}
@@ -74,8 +70,7 @@ void bar() {
// expected-warning@+1 {{'UsingTDWithAttr' is deprecated}}
UsingTDWithAttr objUTDWA;
- // expected-warning@+2 {{'UsingWithCPPAttr' is deprecated}}
- // expected-note@+1 {{in instantiation of template type alias 'UsingWithCPPAttr' requested here}}
+ // expected-warning@+1 {{'UsingWithCPPAttr' is deprecated}}
UsingWithCPPAttr<int> objUsingWCPPA;
// expected-warning@+1 {{'UsingInstWithCPPAttr' is deprecated: Do not use this}}
diff --git a/clang/test/SemaTemplate/alias-templates.cpp b/clang/test/SemaTemplate/alias-templates.cpp
index ab5cad7..09fe72e 100644
--- a/clang/test/SemaTemplate/alias-templates.cpp
+++ b/clang/test/SemaTemplate/alias-templates.cpp
@@ -312,3 +312,11 @@ namespace resolved_nttp {
using TC2 = decltype(C<bool, 2, 3>::p); // expected-note {{instantiation of}}
}
+
+namespace OuterSubstFailure {
+ template <class T> struct A {
+ template <class> using B = T&;
+ // expected-error@-1 {{cannot form a reference to 'void'}}
+ };
+ template struct A<void>; // expected-note {{requested here}}
+} // namespace OuterSubstFailure
diff --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp
index 6d29f8b..e5e081f 100644
--- a/clang/test/SemaTemplate/concepts.cpp
+++ b/clang/test/SemaTemplate/concepts.cpp
@@ -1333,4 +1333,75 @@ static_assert(__cpp17_iterator<not_move_constructible>); \
// expected-note@#is_move_constructible_v {{because 'is_move_constructible_v<parameter_mapping_regressions::case3::not_move_constructible>' evaluated to false}}
}
+namespace case4 {
+
+template<bool b>
+concept bool_ = b;
+
+template<typename... Ts>
+concept unary = bool_<sizeof...(Ts) == 1>;
+
+static_assert(!unary<>);
+static_assert(unary<void>);
+
+}
+
+namespace case5 {
+
+template<int size>
+concept true1 = size == size;
+
+template<typename... Ts>
+concept true2 = true1<sizeof...(Ts)>;
+
+template<typename... Ts>
+concept true3 = true2<Ts...>;
+
+static_assert(true3<void>);
+
+}
+
+namespace case6 {
+
+namespace std {
+template <int __v>
+struct integral_constant {
+ static const int value = __v;
+};
+
+template <class _Tp, class... _Args>
+constexpr bool is_constructible_v = __is_constructible(_Tp, _Args...);
+
+template <class _From, class _To>
+constexpr bool is_convertible_v = __is_convertible(_From, _To);
+
+template <class>
+struct tuple_size;
+
+template <class _Tp>
+constexpr decltype(sizeof(int)) tuple_size_v = tuple_size<_Tp>::value;
+} // namespace std
+
+template <int N, int X>
+concept FixedExtentConstructibleFromExtent = X == N;
+
+template <int Extent>
+struct span {
+ int static constexpr extent = Extent;
+ template <typename R, int N = std::tuple_size_v<R>>
+ requires(FixedExtentConstructibleFromExtent<extent, N>)
+ span(R);
+};
+
+template <class, int>
+struct array {};
+
+template <class _Tp, decltype(sizeof(int)) _Size>
+struct std::tuple_size<array<_Tp, _Size>> : integral_constant<_Size> {};
+
+static_assert(std::is_convertible_v<array<int, 3>, span<3>>);
+static_assert(!std::is_constructible_v<span<4>, array<int, 3>>);
+
+}
+
}