diff options
Diffstat (limited to 'clang')
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>>); + +} + } |