aboutsummaryrefslogtreecommitdiff
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/docs/ReleaseNotes.rst5
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td10
-rw-r--r--clang/include/clang/Basic/OpenACCKinds.h3
-rw-r--r--clang/lib/AST/ASTImporter.cpp34
-rw-r--r--clang/lib/AST/FormatString.cpp1
-rw-r--r--clang/lib/AST/Interp/Interp.cpp4
-rw-r--r--clang/lib/AST/Interp/Interp.h6
-rw-r--r--clang/lib/Basic/Targets/RISCV.cpp19
-rw-r--r--clang/lib/Driver/ToolChains/MinGW.cpp25
-rw-r--r--clang/lib/Format/TokenAnnotator.cpp8
-rw-r--r--clang/lib/Lex/ModuleMap.cpp4
-rw-r--r--clang/lib/Parse/ParseOpenACC.cpp26
-rw-r--r--clang/lib/Sema/SemaInit.cpp52
-rw-r--r--clang/lib/Sema/SemaOverload.cpp94
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp25
-rw-r--r--clang/test/AST/Interp/arrays.cpp8
-rw-r--r--clang/test/CXX/over/over.load/p2-0x.cpp5
-rw-r--r--clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp29
-rw-r--r--clang/test/CodeGen/RISCV/riscv-func-attr-target.c8
-rw-r--r--clang/test/Driver/linker-wrapper-image.c2
-rw-r--r--clang/test/Driver/mingw-sysroot.cpp28
-rw-r--r--clang/test/Driver/riscv-rvv-vector-bits.c2
-rw-r--r--clang/test/Modules/Inputs/AutolinkTBD.framework/AutolinkTBD.tbd1
-rw-r--r--clang/test/Modules/Inputs/AutolinkTBD.framework/Headers/AutolinkTBD.h1
-rw-r--r--clang/test/Modules/autolinkTBD.m16
-rw-r--r--clang/test/Modules/autolink_private_module.m25
-rw-r--r--clang/test/Modules/explicit-specializations.cppm133
-rw-r--r--clang/test/ParserOpenACC/parse-clauses.c84
-rw-r--r--clang/test/Sema/attr-format-Float16.c16
-rw-r--r--clang/test/SemaCXX/attr-format-Float16.cpp24
-rw-r--r--clang/unittests/Format/FormatTest.cpp2
-rw-r--r--clang/unittests/Format/TokenAnnotatorTest.cpp9
32 files changed, 550 insertions, 159 deletions
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9b6e00b..c9b577b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -857,6 +857,11 @@ Bug Fixes to C++ Support
(`#64607 <https://github.com/llvm/llvm-project/issues/64607>`_)
(`#64086 <https://github.com/llvm/llvm-project/issues/64086>`_)
+- Fixed a regression where clang forgets how to substitute into constraints on template-template
+ parameters. Fixes:
+ (`#57410 <https://github.com/llvm/llvm-project/issues/57410>`_) and
+ (`#76604 <https://github.com/llvm/llvm-project/issues/57410>`_)
+
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
- Fixed an import failure of recursive friend class template.
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d150e08..a97182c 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6160,23 +6160,19 @@ def err_illegal_initializer_type : Error<"illegal initializer type %0">;
def ext_init_list_type_narrowing : ExtWarn<
"type %0 cannot be narrowed to %1 in initializer list">,
InGroup<CXX11Narrowing>, DefaultError, SFINAEFailure;
-// *_narrowing_const_reference diagnostics have the same messages, but are
-// controlled by -Wc++11-narrowing-const-reference for narrowing involving a
-// const reference.
def ext_init_list_type_narrowing_const_reference : ExtWarn<
- "type %0 cannot be narrowed to %1 in initializer list">,
+ ext_init_list_type_narrowing.Summary>,
InGroup<CXX11NarrowingConstReference>, DefaultError, SFINAEFailure;
def ext_init_list_variable_narrowing : ExtWarn<
"non-constant-expression cannot be narrowed from type %0 to %1 in "
"initializer list">, InGroup<CXX11Narrowing>, DefaultError, SFINAEFailure;
def ext_init_list_variable_narrowing_const_reference : ExtWarn<
- "non-constant-expression cannot be narrowed from type %0 to %1 in "
- "initializer list">, InGroup<CXX11NarrowingConstReference>, DefaultError, SFINAEFailure;
+ ext_init_list_variable_narrowing.Summary>, InGroup<CXX11NarrowingConstReference>, DefaultError, SFINAEFailure;
def ext_init_list_constant_narrowing : ExtWarn<
"constant expression evaluates to %0 which cannot be narrowed to type %1">,
InGroup<CXX11Narrowing>, DefaultError, SFINAEFailure;
def ext_init_list_constant_narrowing_const_reference : ExtWarn<
- "constant expression evaluates to %0 which cannot be narrowed to type %1">,
+ ext_init_list_constant_narrowing.Summary>,
InGroup<CXX11NarrowingConstReference>, DefaultError, SFINAEFailure;
def warn_init_list_type_narrowing : Warning<
"type %0 cannot be narrowed to %1 in initializer list in C++11">,
diff --git a/clang/include/clang/Basic/OpenACCKinds.h b/clang/include/clang/Basic/OpenACCKinds.h
index 3eb0bf8..f6a628d 100644
--- a/clang/include/clang/Basic/OpenACCKinds.h
+++ b/clang/include/clang/Basic/OpenACCKinds.h
@@ -93,6 +93,9 @@ enum class OpenACCClauseKind {
/// 'default' clause, allowed on parallel, serial, kernel (and compound)
/// constructs.
Default,
+ /// 'if' clause, allowed on all the Compute Constructs, Data Constructs,
+ /// Executable Constructs, and Combined Constructs.
+ If,
/// Represents an invalid clause, for the purposes of parsing.
Invalid,
};
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 9ffae72..5e5570b 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -2034,23 +2034,25 @@ ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
return ToDCOrErr.takeError();
}
- DeclContext *ToDC = *ToDCOrErr;
- // Remove all declarations, which may be in wrong order in the
- // lexical DeclContext and then add them in the proper order.
- for (auto *D : FromDC->decls()) {
- if (!MightNeedReordering(D))
- continue;
+ if (const auto *FromRD = dyn_cast<RecordDecl>(FromDC)) {
+ DeclContext *ToDC = *ToDCOrErr;
+ // Remove all declarations, which may be in wrong order in the
+ // lexical DeclContext and then add them in the proper order.
+ for (auto *D : FromRD->decls()) {
+ if (!MightNeedReordering(D))
+ continue;
- assert(D && "DC contains a null decl");
- if (Decl *ToD = Importer.GetAlreadyImportedOrNull(D)) {
- // Remove only the decls which we successfully imported.
- assert(ToDC == ToD->getLexicalDeclContext() && ToDC->containsDecl(ToD));
- // Remove the decl from its wrong place in the linked list.
- ToDC->removeDecl(ToD);
- // Add the decl to the end of the linked list.
- // This time it will be at the proper place because the enclosing for
- // loop iterates in the original (good) order of the decls.
- ToDC->addDeclInternal(ToD);
+ assert(D && "DC contains a null decl");
+ if (Decl *ToD = Importer.GetAlreadyImportedOrNull(D)) {
+ // Remove only the decls which we successfully imported.
+ assert(ToDC == ToD->getLexicalDeclContext() && ToDC->containsDecl(ToD));
+ // Remove the decl from its wrong place in the linked list.
+ ToDC->removeDecl(ToD);
+ // Add the decl to the end of the linked list.
+ // This time it will be at the proper place because the enclosing for
+ // loop iterates in the original (good) order of the decls.
+ ToDC->addDeclInternal(ToD);
+ }
}
}
diff --git a/clang/lib/AST/FormatString.cpp b/clang/lib/AST/FormatString.cpp
index e0c9e18..c5d14b4 100644
--- a/clang/lib/AST/FormatString.cpp
+++ b/clang/lib/AST/FormatString.cpp
@@ -488,7 +488,6 @@ ArgType::matchesType(ASTContext &C, QualType argTy) const {
return NoMatchPromotionTypeConfusion;
break;
case BuiltinType::Half:
- case BuiltinType::Float16:
case BuiltinType::Float:
if (T == C.DoubleTy)
return MatchPromotion;
diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index a82d1c3..21ea250 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -290,10 +290,10 @@ bool CheckInitialized(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
}
bool CheckLoad(InterpState &S, CodePtr OpPC, const Pointer &Ptr) {
- if (!CheckDummy(S, OpPC, Ptr))
- return false;
if (!CheckLive(S, OpPC, Ptr, AK_Read))
return false;
+ if (!CheckDummy(S, OpPC, Ptr))
+ return false;
if (!CheckExtern(S, OpPC, Ptr))
return false;
if (!CheckRange(S, OpPC, Ptr, AK_Read))
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 828d4ea..c05dea0 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1813,9 +1813,6 @@ inline bool ArrayElemPtr(InterpState &S, CodePtr OpPC) {
const T &Offset = S.Stk.pop<T>();
const Pointer &Ptr = S.Stk.peek<Pointer>();
- if (!CheckArray(S, OpPC, Ptr))
- return false;
-
if (!OffsetHelper<T, ArithOp::Add>(S, OpPC, Offset, Ptr))
return false;
@@ -1843,9 +1840,6 @@ inline bool ArrayElemPtrPop(InterpState &S, CodePtr OpPC) {
const T &Offset = S.Stk.pop<T>();
const Pointer &Ptr = S.Stk.pop<Pointer>();
- if (!CheckArray(S, OpPC, Ptr))
- return false;
-
if (!OffsetHelper<T, ArithOp::Add>(S, OpPC, Offset, Ptr))
return false;
diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp
index 6bc57a8..59ae12e 100644
--- a/clang/lib/Basic/Targets/RISCV.cpp
+++ b/clang/lib/Basic/Targets/RISCV.cpp
@@ -237,22 +237,15 @@ ArrayRef<Builtin::Info> RISCVTargetInfo::getTargetBuiltins() const {
static std::vector<std::string>
collectNonISAExtFeature(ArrayRef<std::string> FeaturesNeedOverride, int XLen) {
- auto ParseResult =
- llvm::RISCVISAInfo::parseFeatures(XLen, FeaturesNeedOverride);
-
- if (!ParseResult) {
- consumeError(ParseResult.takeError());
- return std::vector<std::string>();
- }
-
- std::vector<std::string> ImpliedFeatures = (*ParseResult)->toFeatureVector();
-
std::vector<std::string> NonISAExtFeatureVec;
+ auto IsNonISAExtFeature = [](const std::string &Feature) {
+ assert(Feature.size() > 1 && (Feature[0] == '+' || Feature[0] == '-'));
+ StringRef Ext = StringRef(Feature).drop_front(); // drop the +/-
+ return !llvm::RISCVISAInfo::isSupportedExtensionFeature(Ext);
+ };
llvm::copy_if(FeaturesNeedOverride, std::back_inserter(NonISAExtFeatureVec),
- [&](const std::string &Feat) {
- return !llvm::is_contained(ImpliedFeatures, Feat);
- });
+ IsNonISAExtFeature);
return NonISAExtFeatureVec;
}
diff --git a/clang/lib/Driver/ToolChains/MinGW.cpp b/clang/lib/Driver/ToolChains/MinGW.cpp
index 65512f1..18fc9d4 100644
--- a/clang/lib/Driver/ToolChains/MinGW.cpp
+++ b/clang/lib/Driver/ToolChains/MinGW.cpp
@@ -471,12 +471,23 @@ findClangRelativeSysroot(const Driver &D, const llvm::Triple &LiteralTriple,
return make_error_code(std::errc::no_such_file_or_directory);
}
+static bool looksLikeMinGWSysroot(const std::string &Directory) {
+ StringRef Sep = llvm::sys::path::get_separator();
+ if (!llvm::sys::fs::exists(Directory + Sep + "include" + Sep + "_mingw.h"))
+ return false;
+ if (!llvm::sys::fs::exists(Directory + Sep + "lib" + Sep + "libkernel32.a"))
+ return false;
+ return true;
+}
+
toolchains::MinGW::MinGW(const Driver &D, const llvm::Triple &Triple,
const ArgList &Args)
: ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args),
RocmInstallation(D, Triple, Args) {
getProgramPaths().push_back(getDriver().getInstalledDir());
+ std::string InstallBase =
+ std::string(llvm::sys::path::parent_path(getDriver().getInstalledDir()));
// The sequence for detecting a sysroot here should be kept in sync with
// the testTriple function below.
llvm::Triple LiteralTriple = getLiteralTriple(D, getTriple());
@@ -487,13 +498,17 @@ toolchains::MinGW::MinGW(const Driver &D, const llvm::Triple &Triple,
else if (llvm::ErrorOr<std::string> TargetSubdir = findClangRelativeSysroot(
getDriver(), LiteralTriple, getTriple(), SubdirName))
Base = std::string(llvm::sys::path::parent_path(TargetSubdir.get()));
+ // If the install base of Clang seems to have mingw sysroot files directly
+ // in the toplevel include and lib directories, use this as base instead of
+ // looking for a triple prefixed GCC in the path.
+ else if (looksLikeMinGWSysroot(InstallBase))
+ Base = InstallBase;
else if (llvm::ErrorOr<std::string> GPPName =
findGcc(LiteralTriple, getTriple()))
Base = std::string(llvm::sys::path::parent_path(
llvm::sys::path::parent_path(GPPName.get())));
else
- Base = std::string(
- llvm::sys::path::parent_path(getDriver().getInstalledDir()));
+ Base = InstallBase;
Base += llvm::sys::path::get_separator();
findGccLibDir(LiteralTriple);
@@ -778,9 +793,15 @@ static bool testTriple(const Driver &D, const llvm::Triple &Triple,
if (D.SysRoot.size())
return true;
llvm::Triple LiteralTriple = getLiteralTriple(D, Triple);
+ std::string InstallBase =
+ std::string(llvm::sys::path::parent_path(D.getInstalledDir()));
if (llvm::ErrorOr<std::string> TargetSubdir =
findClangRelativeSysroot(D, LiteralTriple, Triple, SubdirName))
return true;
+ // If the install base itself looks like a mingw sysroot, we'll use that
+ // - don't use any potentially unrelated gcc to influence what triple to use.
+ if (looksLikeMinGWSysroot(InstallBase))
+ return false;
if (llvm::ErrorOr<std::string> GPPName = findGcc(LiteralTriple, Triple))
return true;
// If we neither found a colocated sysroot or a matching gcc executable,
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 3ac3aa3c..8b43438 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -5151,6 +5151,14 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
return true;
if (Left.IsUnterminatedLiteral)
return true;
+ // FIXME: Breaking after newlines seems useful in general. Turn this into an
+ // option and recognize more cases like endl etc, and break independent of
+ // what comes after operator lessless.
+ if (Right.is(tok::lessless) && Right.Next &&
+ Right.Next->is(tok::string_literal) && Left.is(tok::string_literal) &&
+ Left.TokenText.ends_with("\\n\"")) {
+ return true;
+ }
if (Right.is(TT_RequiresClause)) {
switch (Style.RequiresClausePosition) {
case FormatStyle::RCPS_OwnLine:
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index ea5d13d..42d55d0 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -984,7 +984,9 @@ static void inferFrameworkLink(Module *Mod) {
assert(!Mod->isSubFramework() &&
"Can only infer linking for top-level frameworks");
- Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
+ StringRef FrameworkName(Mod->Name);
+ FrameworkName.consume_back("_Private");
+ Mod->LinkLibraries.push_back(Module::LinkLibrary(FrameworkName.str(),
/*IsFramework=*/true));
}
diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp
index 94c3d0c..84e994e 100644
--- a/clang/lib/Parse/ParseOpenACC.cpp
+++ b/clang/lib/Parse/ParseOpenACC.cpp
@@ -80,6 +80,10 @@ OpenACCClauseKind getOpenACCClauseKind(Token Tok) {
if (Tok.is(tok::kw_default))
return OpenACCClauseKind::Default;
+ // if is also a keyword, make sure we parse it correctly.
+ if (Tok.is(tok::kw_if))
+ return OpenACCClauseKind::If;
+
if (!Tok.is(tok::identifier))
return OpenACCClauseKind::Invalid;
@@ -88,6 +92,7 @@ OpenACCClauseKind getOpenACCClauseKind(Token Tok) {
.Case("auto", OpenACCClauseKind::Auto)
.Case("default", OpenACCClauseKind::Default)
.Case("finalize", OpenACCClauseKind::Finalize)
+ .Case("if", OpenACCClauseKind::If)
.Case("if_present", OpenACCClauseKind::IfPresent)
.Case("independent", OpenACCClauseKind::Independent)
.Case("nohost", OpenACCClauseKind::NoHost)
@@ -324,7 +329,7 @@ OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) {
}
bool ClauseHasRequiredParens(OpenACCClauseKind Kind) {
- return Kind == OpenACCClauseKind::Default;
+ return Kind == OpenACCClauseKind::Default || Kind == OpenACCClauseKind::If;
}
bool ParseOpenACCClauseParams(Parser &P, OpenACCClauseKind Kind) {
@@ -356,6 +361,19 @@ bool ParseOpenACCClauseParams(Parser &P, OpenACCClauseKind Kind) {
break;
}
+ case OpenACCClauseKind::If: {
+ // FIXME: It isn't clear if the spec saying 'condition' means the same as
+ // it does in an if/while/etc (See ParseCXXCondition), however as it was
+ // written with Fortran/C in mind, we're going to assume it just means an
+ // 'expression evaluating to boolean'.
+ ExprResult CondExpr =
+ P.getActions().CorrectDelayedTyposInExpr(P.ParseExpression());
+ // An invalid expression can be just about anything, so just give up on
+ // this clause list.
+ if (CondExpr.isInvalid())
+ return true;
+ break;
+ }
default:
llvm_unreachable("Not a required parens type?");
}
@@ -372,8 +390,10 @@ bool ParseOpenACCClauseParams(Parser &P, OpenACCClauseKind Kind) {
// However, they all are named with a single-identifier (or auto/default!)
// token, followed in some cases by either braces or parens.
bool ParseOpenACCClause(Parser &P) {
- if (!P.getCurToken().isOneOf(tok::identifier, tok::kw_auto, tok::kw_default))
- return P.Diag(P.getCurToken(), diag::err_expected) << tok::identifier;
+ // A number of clause names are actually keywords, so accept a keyword that
+ // can be converted to a name.
+ if (expectIdentifierOrKeyword(P))
+ return true;
OpenACCClauseKind Kind = getOpenACCClauseKind(P.getCurToken());
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index e469e42..408ee5f 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -10377,11 +10377,6 @@ void InitializationSequence::dump() const {
dump(llvm::errs());
}
-static bool NarrowingErrs(const LangOptions &L) {
- return L.CPlusPlus11 &&
- (!L.MicrosoftExt || L.isCompatibleWithMSVC(LangOptions::MSVC2015));
-}
-
static void DiagnoseNarrowingInInitList(Sema &S,
const ImplicitConversionSequence &ICS,
QualType PreNarrowingType,
@@ -10402,6 +10397,19 @@ static void DiagnoseNarrowingInInitList(Sema &S,
return;
}
+ auto MakeDiag = [&](bool IsConstRef, unsigned DefaultDiagID,
+ unsigned ConstRefDiagID, unsigned WarnDiagID) {
+ unsigned DiagID;
+ auto &L = S.getLangOpts();
+ if (L.CPlusPlus11 &&
+ (!L.MicrosoftExt || L.isCompatibleWithMSVC(LangOptions::MSVC2015)))
+ DiagID = IsConstRef ? ConstRefDiagID : DefaultDiagID;
+ else
+ DiagID = WarnDiagID;
+ return S.Diag(PostInit->getBeginLoc(), DiagID)
+ << PostInit->getSourceRange();
+ };
+
// C++11 [dcl.init.list]p7: Check whether this is a narrowing conversion.
APValue ConstantValue;
QualType ConstantType;
@@ -10417,13 +10425,9 @@ static void DiagnoseNarrowingInInitList(Sema &S,
// narrowing conversion even if the value is a constant and can be
// represented exactly as an integer.
QualType T = EntityType.getNonReferenceType();
- S.Diag(PostInit->getBeginLoc(),
- NarrowingErrs(S.getLangOpts())
- ? (T == EntityType
- ? diag::ext_init_list_type_narrowing
- : diag::ext_init_list_type_narrowing_const_reference)
- : diag::warn_init_list_type_narrowing)
- << PostInit->getSourceRange()
+ MakeDiag(T != EntityType, diag::ext_init_list_type_narrowing,
+ diag::ext_init_list_type_narrowing_const_reference,
+ diag::warn_init_list_type_narrowing)
<< PreNarrowingType.getLocalUnqualifiedType()
<< T.getLocalUnqualifiedType();
break;
@@ -10431,14 +10435,10 @@ static void DiagnoseNarrowingInInitList(Sema &S,
case NK_Constant_Narrowing: {
// A constant value was narrowed.
- QualType T = EntityType.getNonReferenceType();
- S.Diag(PostInit->getBeginLoc(),
- NarrowingErrs(S.getLangOpts())
- ? (T == EntityType
- ? diag::ext_init_list_constant_narrowing
- : diag::ext_init_list_constant_narrowing_const_reference)
- : diag::warn_init_list_constant_narrowing)
- << PostInit->getSourceRange()
+ MakeDiag(EntityType.getNonReferenceType() != EntityType,
+ diag::ext_init_list_constant_narrowing,
+ diag::ext_init_list_constant_narrowing_const_reference,
+ diag::warn_init_list_constant_narrowing)
<< ConstantValue.getAsString(S.getASTContext(), ConstantType)
<< EntityType.getNonReferenceType().getLocalUnqualifiedType();
break;
@@ -10446,14 +10446,10 @@ static void DiagnoseNarrowingInInitList(Sema &S,
case NK_Variable_Narrowing: {
// A variable's value may have been narrowed.
- QualType T = EntityType.getNonReferenceType();
- S.Diag(PostInit->getBeginLoc(),
- NarrowingErrs(S.getLangOpts())
- ? (T == EntityType
- ? diag::ext_init_list_variable_narrowing
- : diag::ext_init_list_variable_narrowing_const_reference)
- : diag::warn_init_list_variable_narrowing)
- << PostInit->getSourceRange()
+ MakeDiag(EntityType.getNonReferenceType() != EntityType,
+ diag::ext_init_list_variable_narrowing,
+ diag::ext_init_list_variable_narrowing_const_reference,
+ diag::warn_init_list_variable_narrowing)
<< PreNarrowingType.getLocalUnqualifiedType()
<< EntityType.getNonReferenceType().getLocalUnqualifiedType();
break;
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 9fb7671..e6c267b 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -1259,6 +1259,43 @@ static bool IsOverloadOrOverrideImpl(Sema &SemaRef, FunctionDecl *New,
if ((OldTemplate == nullptr) != (NewTemplate == nullptr))
return true;
+ if (NewTemplate) {
+ // C++ [temp.over.link]p4:
+ // The signature of a function template consists of its function
+ // signature, its return type and its template parameter list. The names
+ // of the template parameters are significant only for establishing the
+ // relationship between the template parameters and the rest of the
+ // signature.
+ //
+ // We check the return type and template parameter lists for function
+ // templates first; the remaining checks follow.
+ bool SameTemplateParameterList = SemaRef.TemplateParameterListsAreEqual(
+ NewTemplate, NewTemplate->getTemplateParameters(), OldTemplate,
+ OldTemplate->getTemplateParameters(), false, Sema::TPL_TemplateMatch);
+ bool SameReturnType = SemaRef.Context.hasSameType(
+ Old->getDeclaredReturnType(), New->getDeclaredReturnType());
+ // FIXME(GH58571): Match template parameter list even for non-constrained
+ // template heads. This currently ensures that the code prior to C++20 is
+ // not newly broken.
+ bool ConstraintsInTemplateHead =
+ NewTemplate->getTemplateParameters()->hasAssociatedConstraints() ||
+ OldTemplate->getTemplateParameters()->hasAssociatedConstraints();
+ // C++ [namespace.udecl]p11:
+ // The set of declarations named by a using-declarator that inhabits a
+ // class C does not include member functions and member function
+ // templates of a base class that "correspond" to (and thus would
+ // conflict with) a declaration of a function or function template in
+ // C.
+ // Comparing return types is not required for the "correspond" check to
+ // decide whether a member introduced by a shadow declaration is hidden.
+ if (UseMemberUsingDeclRules && ConstraintsInTemplateHead &&
+ !SameTemplateParameterList)
+ return true;
+ if (!UseMemberUsingDeclRules &&
+ (!SameTemplateParameterList || !SameReturnType))
+ return true;
+ }
+
// Is the function New an overload of the function Old?
QualType OldQType = SemaRef.Context.getCanonicalType(Old->getType());
QualType NewQType = SemaRef.Context.getCanonicalType(New->getType());
@@ -1410,43 +1447,6 @@ static bool IsOverloadOrOverrideImpl(Sema &SemaRef, FunctionDecl *New,
}
}
- if (NewTemplate) {
- // C++ [temp.over.link]p4:
- // The signature of a function template consists of its function
- // signature, its return type and its template parameter list. The names
- // of the template parameters are significant only for establishing the
- // relationship between the template parameters and the rest of the
- // signature.
- //
- // We check the return type and template parameter lists for function
- // templates first; the remaining checks follow.
- bool SameTemplateParameterList = SemaRef.TemplateParameterListsAreEqual(
- NewTemplate, NewTemplate->getTemplateParameters(), OldTemplate,
- OldTemplate->getTemplateParameters(), false, Sema::TPL_TemplateMatch);
- bool SameReturnType = SemaRef.Context.hasSameType(
- Old->getDeclaredReturnType(), New->getDeclaredReturnType());
- // FIXME(GH58571): Match template parameter list even for non-constrained
- // template heads. This currently ensures that the code prior to C++20 is
- // not newly broken.
- bool ConstraintsInTemplateHead =
- NewTemplate->getTemplateParameters()->hasAssociatedConstraints() ||
- OldTemplate->getTemplateParameters()->hasAssociatedConstraints();
- // C++ [namespace.udecl]p11:
- // The set of declarations named by a using-declarator that inhabits a
- // class C does not include member functions and member function
- // templates of a base class that "correspond" to (and thus would
- // conflict with) a declaration of a function or function template in
- // C.
- // Comparing return types is not required for the "correspond" check to
- // decide whether a member introduced by a shadow declaration is hidden.
- if (UseMemberUsingDeclRules && ConstraintsInTemplateHead &&
- !SameTemplateParameterList)
- return true;
- if (!UseMemberUsingDeclRules &&
- (!SameTemplateParameterList || !SameReturnType))
- return true;
- }
-
if (!UseOverrideRules) {
Expr *NewRC = New->getTrailingRequiresClause(),
*OldRC = Old->getTrailingRequiresClause();
@@ -13994,21 +13994,19 @@ ExprResult Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn,
OverloadCandidateSet::iterator Best;
OverloadingResult OverloadResult =
CandidateSet.BestViableFunction(*this, Fn->getBeginLoc(), Best);
- FunctionDecl *FDecl = Best->Function;
// Model the case with a call to a templated function whose definition
// encloses the call and whose return type contains a placeholder type as if
// the UnresolvedLookupExpr was type-dependent.
- if (OverloadResult == OR_Success && FDecl &&
- FDecl->isTemplateInstantiation() &&
- FDecl->getReturnType()->isUndeducedType()) {
- if (auto TP = FDecl->getTemplateInstantiationPattern(false)) {
- if (TP->willHaveBody()) {
- CallExpr *CE =
- CallExpr::Create(Context, Fn, Args, Context.DependentTy, VK_PRValue,
- RParenLoc, CurFPFeatureOverrides());
- result = CE;
- return result;
+ if (OverloadResult == OR_Success) {
+ const FunctionDecl *FDecl = Best->Function;
+ if (FDecl && FDecl->isTemplateInstantiation() &&
+ FDecl->getReturnType()->isUndeducedType()) {
+ if (const auto *TP =
+ FDecl->getTemplateInstantiationPattern(/*ForDefinition=*/false);
+ TP && TP->willHaveBody()) {
+ return CallExpr::Create(Context, Fn, Args, Context.DependentTy,
+ VK_PRValue, RParenLoc, CurFPFeatureOverrides());
}
}
}
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 09dd119..7f20413 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -344,15 +344,26 @@ MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs(
using namespace TemplateInstArgsHelpers;
const Decl *CurDecl = ND;
+
+ if (!CurDecl)
+ CurDecl = Decl::castFromDeclContext(DC);
+
if (Innermost) {
Result.addOuterTemplateArguments(const_cast<NamedDecl *>(ND),
Innermost->asArray(), Final);
- CurDecl = Response::UseNextDecl(ND).NextDecl;
+ // Populate placeholder template arguments for TemplateTemplateParmDecls.
+ // This is essential for the case e.g.
+ //
+ // template <class> concept Concept = false;
+ // template <template <Concept C> class T> void foo(T<int>)
+ //
+ // where parameter C has a depth of 1 but the substituting argument `int`
+ // has a depth of 0.
+ if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(CurDecl))
+ HandleDefaultTempArgIntoTempTempParam(TTP, Result);
+ CurDecl = Response::UseNextDecl(CurDecl).NextDecl;
}
- if (!ND)
- CurDecl = Decl::castFromDeclContext(DC);
-
while (!CurDecl->isFileContextDecl()) {
Response R;
if (const auto *VarTemplSpec =
@@ -380,10 +391,8 @@ MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs(
R = Response::ChangeDecl(CTD->getLexicalDeclContext());
} else if (!isa<DeclContext>(CurDecl)) {
R = Response::DontClearRelativeToPrimaryNextDecl(CurDecl);
- if (CurDecl->getDeclContext()->isTranslationUnit()) {
- if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(CurDecl)) {
- R = HandleDefaultTempArgIntoTempTempParam(TTP, Result);
- }
+ if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(CurDecl)) {
+ R = HandleDefaultTempArgIntoTempTempParam(TTP, Result);
}
} else {
R = HandleGenericDeclContext(CurDecl);
diff --git a/clang/test/AST/Interp/arrays.cpp b/clang/test/AST/Interp/arrays.cpp
index c455731..4aa10da5 100644
--- a/clang/test/AST/Interp/arrays.cpp
+++ b/clang/test/AST/Interp/arrays.cpp
@@ -72,6 +72,14 @@ constexpr int getElementFromEnd(const int *Arr, int size, int index) {
static_assert(getElementFromEnd(data, 5, 0) == 1, "");
static_assert(getElementFromEnd(data, 5, 4) == 5, "");
+constexpr int getFirstElem(const int *a) {
+ return a[0]; // expected-note {{read of dereferenced null pointer}} \
+ // ref-note {{read of dereferenced null pointer}}
+}
+static_assert(getFirstElem(nullptr) == 1, ""); // expected-error {{not an integral constant expression}} \
+ // expected-note {{in call to}} \
+ // ref-error {{not an integral constant expression}} \
+ // ref-note {{in call to}}
constexpr static int arr[2] = {1,2};
constexpr static int arr2[2] = {3,4};
diff --git a/clang/test/CXX/over/over.load/p2-0x.cpp b/clang/test/CXX/over/over.load/p2-0x.cpp
index 183f3cb..8fd9a1c 100644
--- a/clang/test/CXX/over/over.load/p2-0x.cpp
+++ b/clang/test/CXX/over/over.load/p2-0x.cpp
@@ -24,6 +24,11 @@ class Y {
void k() &&; // expected-error{{cannot overload a member function with ref-qualifier '&&' with a member function without a ref-qualifier}}
};
+struct GH76358 {
+ template<int> void f() && {}
+ template<typename T> void f() const {}
+};
+
#if __cplusplus >= 202002L
namespace GH58962 {
diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
index 449b623..f586069 100644
--- a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
+++ b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
@@ -59,3 +59,32 @@ struct Nothing {};
// FIXME: Wait the standard to clarify the intent.
template<> template<> Z<Nothing> S5<Z>::V<Nothing>;
+
+namespace GH57410 {
+
+template<typename T>
+concept True = true;
+
+template<typename T>
+concept False = false; // #False
+
+template <class> struct S {};
+
+template<template<True T> typename Wrapper>
+using Test = Wrapper<int>;
+
+template<template<False T> typename Wrapper> // #TTP-Wrapper
+using Test = Wrapper<int>; // expected-error {{constraints not satisfied for template template parameter 'Wrapper' [with T = int]}}
+
+// expected-note@#TTP-Wrapper {{'int' does not satisfy 'False'}}
+// expected-note@#False {{evaluated to false}}
+
+template <typename U, template<False> typename T>
+void foo(T<U>); // #foo
+
+void bar() {
+ foo<int>(S<int>{}); // expected-error {{no matching function for call to 'foo'}}
+ // expected-note@#foo {{substitution failure [with U = int]: constraints not satisfied for template template parameter 'T' [with $0 = int]}}
+}
+
+}
diff --git a/clang/test/CodeGen/RISCV/riscv-func-attr-target.c b/clang/test/CodeGen/RISCV/riscv-func-attr-target.c
index 506acab..759c33a 100644
--- a/clang/test/CodeGen/RISCV/riscv-func-attr-target.c
+++ b/clang/test/CodeGen/RISCV/riscv-func-attr-target.c
@@ -40,8 +40,8 @@ __attribute__((target("cpu=sifive-u54"))) void testAttrCpuOnly() {}
// CHECK: attributes #1 = { {{.*}}"target-cpu"="rocket-rv64" "target-features"="+64bit,+a,+d,+f,+m,+save-restore,+v,+zicsr,+zifencei,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl32b,+zvl64b,-relax,-zbb,-zfa" "tune-cpu"="generic-rv64" }
// CHECK: attributes #2 = { {{.*}}"target-features"="+64bit,+a,+m,+save-restore,+zbb,+zifencei,-relax,-zfa" }
// CHECK: attributes #3 = { {{.*}}"target-features"="+64bit,+a,+d,+experimental-zicond,+f,+m,+save-restore,+v,+zbb,+zicsr,+zifencei,+zve32f,+zve32x,+zve64d,+zve64f,+zve64x,+zvl128b,+zvl32b,+zvl64b,-relax,-zfa" }
-// CHECK: attributes #4 = { {{.*}}"target-features"="+64bit,+a,+c,+d,+f,+m,+save-restore,+zbb,+zicsr,+zifencei,-relax,-zfa" }
-// CHECK: attributes #5 = { {{.*}}"target-features"="+64bit,+m,+save-restore,-relax,-zbb,-zfa" }
+// CHECK: attributes #4 = { {{.*}}"target-features"="+64bit,+a,+c,+d,+f,+m,+save-restore,+zbb,+zicsr,+zifencei,-relax" }
+// CHECK: attributes #5 = { {{.*}}"target-features"="+64bit,+m,+save-restore,-relax" }
// CHECK: attributes #6 = { {{.*}}"target-cpu"="sifive-u54" "target-features"="+64bit,+a,+m,+save-restore,+zbb,+zifencei,-relax,-zfa" }
-// CHECK: attributes #7 = { {{.*}}"target-cpu"="sifive-u54" "target-features"="+64bit,+m,+save-restore,-relax,-zbb,-zfa" }
-// CHECK: attributes #8 = { {{.*}}"target-cpu"="sifive-u54" "target-features"="+64bit,+a,+c,+d,+f,+m,+save-restore,+zicsr,+zifencei,-relax,-zbb,-zfa" }
+// CHECK: attributes #7 = { {{.*}}"target-cpu"="sifive-u54" "target-features"="+64bit,+m,+save-restore,-relax" }
+// CHECK: attributes #8 = { {{.*}}"target-cpu"="sifive-u54" "target-features"="+64bit,+a,+c,+d,+f,+m,+save-restore,+zicsr,+zifencei,-relax" }
diff --git a/clang/test/Driver/linker-wrapper-image.c b/clang/test/Driver/linker-wrapper-image.c
index 40dde2e..03caa1e 100644
--- a/clang/test/Driver/linker-wrapper-image.c
+++ b/clang/test/Driver/linker-wrapper-image.c
@@ -19,7 +19,7 @@
// OPENMP-COFF: @__start_omp_offloading_entries = hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "omp_offloading_entries$OA"
// OPENMP-COFF-NEXT: @__stop_omp_offloading_entries = hidden constant [0 x %struct.__tgt_offload_entry] zeroinitializer, section "omp_offloading_entries$OZ"
-// OPENMP-NEXT: @.omp_offloading.device_image = internal unnamed_addr constant [[[SIZE:[0-9]+]] x i8] c"\10\FF\10\AD\01{{.*}}", section ".llvm.offloading", align 8
+// OPENMP: @.omp_offloading.device_image = internal unnamed_addr constant [[[SIZE:[0-9]+]] x i8] c"\10\FF\10\AD{{.*}}", section ".llvm.offloading", align 8
// OPENMP-NEXT: @.omp_offloading.device_images = internal unnamed_addr constant [1 x %__tgt_device_image] [%__tgt_device_image { ptr getelementptr inbounds ([[[BEGIN:[0-9]+]] x i8], ptr @.omp_offloading.device_image, i64 1, i64 0), ptr getelementptr inbounds ([[[END:[0-9]+]] x i8], ptr @.omp_offloading.device_image, i64 1, i64 0), ptr @__start_omp_offloading_entries, ptr @__stop_omp_offloading_entries }]
// OPENMP-NEXT: @.omp_offloading.descriptor = internal constant %__tgt_bin_desc { i32 1, ptr @.omp_offloading.device_images, ptr @__start_omp_offloading_entries, ptr @__stop_omp_offloading_entries }
// OPENMP-NEXT: @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @.omp_offloading.descriptor_reg, ptr null }]
diff --git a/clang/test/Driver/mingw-sysroot.cpp b/clang/test/Driver/mingw-sysroot.cpp
index 911dab4..50152b2 100644
--- a/clang/test/Driver/mingw-sysroot.cpp
+++ b/clang/test/Driver/mingw-sysroot.cpp
@@ -14,6 +14,12 @@
// RUN: ln -s %S/Inputs/mingw_ubuntu_posix_tree/usr/x86_64-w64-mingw32 %T/testroot-clang/x86_64-w64-mingw32
// RUN: ln -s %S/Inputs/mingw_arch_tree/usr/i686-w64-mingw32 %T/testroot-clang/i686-w64-mingw32
+// RUN: rm -rf %T/testroot-clang-native
+// RUN: mkdir -p %T/testroot-clang-native/bin
+// RUN: ln -s %clang %T/testroot-clang-native/bin/clang
+// RUN: mkdir -p %T/testroot-clang-native/include/_mingw.h
+// RUN: mkdir -p %T/testroot-clang-native/lib/libkernel32.a
+
// RUN: rm -rf %T/testroot-custom-triple
// RUN: mkdir -p %T/testroot-custom-triple/bin
// RUN: ln -s %clang %T/testroot-custom-triple/bin/clang
@@ -58,6 +64,28 @@
// RUN: env "PATH=%T/testroot-gcc/bin:%PATH%" %T/testroot-gcc/bin/x86_64-w64-mingw32-clang -target x86_64-w64-mingw32 -rtlib=platform -stdlib=libstdc++ --sysroot="" -c -### %s 2>&1 | FileCheck -check-prefix=CHECK_TESTROOT_GCC %s
+// If we're executing clang from a directory with what looks like a mingw sysroot,
+// with headers in <base>/include and libs in <base>/lib, use that rather than looking
+// for another GCC in the path.
+//
+// Note, this test has a surprising quirk: We're testing with an install directory,
+// testroot-clang-native, which lacks the "x86_64-w64-mingw32" subdirectory, it only
+// has the include and lib subdirectories without any triple prefix.
+//
+// Since commit fd15cb935d7aae25ad62bfe06fe9f17cea585978, we avoid using the
+// <base>/include and <base>/lib directories when cross compiling. So technically, this
+// case testcase only works exactly as expected when running on x86_64 Windows, when
+// this target isn't considered cross compiling.
+//
+// However we do still pass the include directory <base>/x86_64-w64-mingw32/include to
+// the -cc1 interface, even if it is missing. Thus, this test looks for this path name,
+// that indicates that we did choose the right base, even if this particular directory
+// actually doesn't exist here.
+
+// RUN: env "PATH=%T/testroot-gcc/bin:%PATH%" %T/testroot-clang-native/bin/clang -target x86_64-w64-mingw32 -rtlib=compiler-rt -stdlib=libstdc++ --sysroot="" -c -### %s 2>&1 | FileCheck -check-prefix=CHECK_TESTROOT_CLANG_NATIVE %s
+// CHECK_TESTROOT_CLANG_NATIVE: "{{[^"]+}}/testroot-clang-native{{/|\\\\}}x86_64-w64-mingw32{{/|\\\\}}include"
+
+
// If the user requests a different arch via the -m32 option, which changes
// x86_64 into i386, check that the driver notices that it can't find a
// sysroot for i386 but there is one for i686, and uses that one.
diff --git a/clang/test/Driver/riscv-rvv-vector-bits.c b/clang/test/Driver/riscv-rvv-vector-bits.c
index e92b66c..24af5f0 100644
--- a/clang/test/Driver/riscv-rvv-vector-bits.c
+++ b/clang/test/Driver/riscv-rvv-vector-bits.c
@@ -44,7 +44,7 @@
// CHECK-BAD-VALUE-ERROR: error: unsupported argument '{{.*}}' to option '-mrvv-vector-bits='
-// Error if using attribute without -msve-vector-bits=<bits> or if using -msve-vector-bits=<bits>+ syntax
+// Error if using attribute without -mrvv-vector-bits=<bits> or if using -mrvv-vector-bits=<bits>+ syntax
// -----------------------------------------------------------------------------
// RUN: not %clang -c %s -o /dev/null -target riscv64-linux-gnu \
// RUN: -march=rv64gc_zve64x 2>&1 | FileCheck --check-prefix=CHECK-NO-FLAG-ERROR %s
diff --git a/clang/test/Modules/Inputs/AutolinkTBD.framework/AutolinkTBD.tbd b/clang/test/Modules/Inputs/AutolinkTBD.framework/AutolinkTBD.tbd
deleted file mode 100644
index 4aa0f85..0000000
--- a/clang/test/Modules/Inputs/AutolinkTBD.framework/AutolinkTBD.tbd
+++ /dev/null
@@ -1 +0,0 @@
-empty file - clang only needs to check if it exists.
diff --git a/clang/test/Modules/Inputs/AutolinkTBD.framework/Headers/AutolinkTBD.h b/clang/test/Modules/Inputs/AutolinkTBD.framework/Headers/AutolinkTBD.h
deleted file mode 100644
index 914983c..0000000
--- a/clang/test/Modules/Inputs/AutolinkTBD.framework/Headers/AutolinkTBD.h
+++ /dev/null
@@ -1 +0,0 @@
-extern int foo(void);
diff --git a/clang/test/Modules/autolinkTBD.m b/clang/test/Modules/autolinkTBD.m
deleted file mode 100644
index 69253294..0000000
--- a/clang/test/Modules/autolinkTBD.m
+++ /dev/null
@@ -1,16 +0,0 @@
-// UNSUPPORTED: target={{.*}}-zos{{.*}}, target={{.*}}-aix{{.*}}
-// RUN: rm -rf %t
-// RUN: %clang_cc1 -emit-llvm -o - -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs %s | FileCheck %s
-// RUN: %clang_cc1 -emit-llvm -fno-autolink -o - -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -F %S/Inputs %s | FileCheck --check-prefix=CHECK-AUTOLINK-DISABLED %s
-
-@import AutolinkTBD;
-
-int f(void) {
- return foo();
-}
-
-// CHECK: !llvm.linker.options = !{![[AUTOLINK_FRAMEWORK:[0-9]+]]}
-// CHECK: ![[AUTOLINK_FRAMEWORK]] = !{!"-framework", !"AutolinkTBD"}
-
-// CHECK-AUTOLINK-DISABLED: !llvm.module.flags
-// CHECK-AUTOLINK-DISABLED-NOT: !llvm.linker.options
diff --git a/clang/test/Modules/autolink_private_module.m b/clang/test/Modules/autolink_private_module.m
new file mode 100644
index 0000000..54bebc3
--- /dev/null
+++ b/clang/test/Modules/autolink_private_module.m
@@ -0,0 +1,25 @@
+// Test that autolink hints for frameworks don't use the private module name.
+// RUN: rm -rf %t && mkdir %t
+// RUN: split-file %s %t
+
+// RUN: %clang_cc1 -emit-llvm -o - -fmodules-cache-path=%t/ModuleCache -fmodules -fimplicit-module-maps -F %t/Frameworks %t/test.m | FileCheck %s
+
+// CHECK: !{!"-framework", !"Autolink"}
+// CHECK-NOT: !{!"-framework", !"Autolink_Private"}
+
+//--- test.m
+#include <Autolink/Autolink.h>
+#include <Autolink/Autolink_Private.h>
+
+//--- Frameworks/Autolink.framework/Headers/Autolink.h
+void public();
+
+//--- Frameworks/Autolink.framework/PrivateHeaders/Autolink_Private.h
+void private();
+
+//--- Frameworks/Autolink.framework/Modules/module.modulemap
+framework module Autolink { header "Autolink.h"}
+
+//--- Frameworks/Autolink.framework/Modules/module.private.modulemap
+framework module Autolink_Private { header "Autolink_Private.h"}
+
diff --git a/clang/test/Modules/explicit-specializations.cppm b/clang/test/Modules/explicit-specializations.cppm
new file mode 100644
index 0000000..9141440
--- /dev/null
+++ b/clang/test/Modules/explicit-specializations.cppm
@@ -0,0 +1,133 @@
+// Testing that the compiler can select the correct template specialization
+// from different template aliasing.
+//
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+// RUN: cd %t
+//
+// RUN: %clang_cc1 -std=c++20 %t/a.cppm -emit-module-interface -o %t/a.pcm
+// RUN: %clang_cc1 -std=c++20 %t/b.cpp -fprebuilt-module-path=%t \
+// RUN: -fsyntax-only -verify
+
+//--- a.cppm
+
+// For template type parameters
+export module a;
+export template <class C>
+struct S {
+ static constexpr bool selected = false;
+};
+
+export struct A {};
+
+export template <>
+struct S<A> {
+ static constexpr bool selected = true;
+};
+
+export using B = A;
+
+// For template template parameters
+
+export template <template<typename> typename C>
+struct V {
+ static constexpr bool selected = false;
+};
+
+export template <>
+struct V<S> {
+ static constexpr bool selected = true;
+};
+
+// For template non type parameters
+export template <int X>
+struct Numbers {
+ static constexpr bool selected = false;
+ static constexpr int value = X;
+};
+
+export template<>
+struct Numbers<43> {
+ static constexpr bool selected = true;
+ static constexpr int value = 43;
+};
+
+export template <const int *>
+struct Pointers {
+ static constexpr bool selected = false;
+};
+
+export int IntegralValue = 0;
+export template<>
+struct Pointers<&IntegralValue> {
+ static constexpr bool selected = true;
+};
+
+export template <void *>
+struct NullPointers {
+ static constexpr bool selected = false;
+};
+
+export template<>
+struct NullPointers<nullptr> {
+ static constexpr bool selected = true;
+};
+
+export template<int (&)[5]>
+struct Array {
+ static constexpr bool selected = false;
+};
+
+export int array[5];
+export template<>
+struct Array<array> {
+ static constexpr bool selected = true;
+};
+
+//--- b.cpp
+// expected-no-diagnostics
+import a;
+
+// Testing for different qualifiers
+static_assert(S<B>::selected);
+static_assert(S<::B>::selected);
+static_assert(::S<B>::selected);
+static_assert(::S<::B>::selected);
+typedef A C;
+static_assert(S<C>::selected);
+static_assert(S<::C>::selected);
+static_assert(::S<C>::selected);
+static_assert(::S<::C>::selected);
+
+namespace D {
+ C getAType();
+ typedef C E;
+}
+
+static_assert(S<D::E>::selected);
+static_assert(S<decltype(D::getAType())>::selected);
+
+// Testing we can select the correct specialization for different
+// template template argument alising.
+
+static_assert(V<S>::selected);
+static_assert(V<::S>::selected);
+static_assert(::V<S>::selected);
+static_assert(::V<::S>::selected);
+
+// Testing for template non type parameters
+static_assert(Numbers<43>::selected);
+static_assert(Numbers<21 * 2 + 1>::selected);
+static_assert(Numbers<42 + 1>::selected);
+static_assert(Numbers<44 - 1>::selected);
+static_assert(Numbers<Numbers<43>::value>::selected);
+static_assert(!Numbers<44>::selected);
+
+static_assert(Pointers<&IntegralValue>::selected);
+static_assert(!Pointers<nullptr>::selected);
+static_assert(NullPointers<nullptr>::selected);
+static_assert(!NullPointers<(void*)&IntegralValue>::selected);
+
+static_assert(Array<array>::selected);
+int another_array[5];
+static_assert(!Array<another_array>::selected);
diff --git a/clang/test/ParserOpenACC/parse-clauses.c b/clang/test/ParserOpenACC/parse-clauses.c
index aedf0c7..b247210 100644
--- a/clang/test/ParserOpenACC/parse-clauses.c
+++ b/clang/test/ParserOpenACC/parse-clauses.c
@@ -148,8 +148,92 @@ void DefaultClause() {
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc serial default(present), seq
for(;;){}
+}
+
+void IfClause() {
+ // expected-error@+2{{expected '('}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial loop if
+ for(;;){}
+ // expected-error@+2{{expected '('}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial if seq
+ for(;;){}
+
+ // expected-error@+2{{expected '('}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial if, seq
+ for(;;){}
+
+ // expected-error@+2{{expected expression}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial if(
+ for(;;){}
+ // expected-error@+2{{use of undeclared identifier 'seq'}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial if( seq
+ for(;;){}
+
+ // expected-error@+3{{expected expression}}
+ // expected-error@+2{{use of undeclared identifier 'seq'}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial if(, seq
+ for(;;){}
+
+ // expected-error@+3{{expected '('}}
+ // expected-error@+2{{expected identifier}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial if)
+ for(;;){}
+
+ // expected-error@+3{{expected '('}}
+ // expected-error@+2{{expected identifier}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial if) seq
+ for(;;){}
+
+ // expected-error@+3{{expected '('}}
+ // expected-error@+2{{expected identifier}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial if), seq
+ for(;;){}
+
+ // expected-error@+2{{expected expression}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial if()
+ for(;;){}
+
+ // expected-error@+2{{expected expression}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial if() seq
+ for(;;){}
+
+ // expected-error@+2{{expected expression}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial if(), seq
+ for(;;){}
+
+ // expected-error@+2{{use of undeclared identifier 'invalid_expr'}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial if(invalid_expr)
+ for(;;){}
+
+ // expected-error@+2{{expected expression}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial if() seq
+ for(;;){}
+
+ int i, j;
+
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial if(i > j)
+ for(;;){}
+
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc serial if(1+5>3), seq
+ for(;;){}
}
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
diff --git a/clang/test/Sema/attr-format-Float16.c b/clang/test/Sema/attr-format-Float16.c
new file mode 100644
index 0000000..6c3dfe1
--- /dev/null
+++ b/clang/test/Sema/attr-format-Float16.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -triple i686-linux-pc -target-feature +sse2 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-linux-pc %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple spir-unknown-unknown %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple armv7a-linux-gnu %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple aarch64-linux-gnu %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple riscv32 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple riscv64 %s
+
+void a(const char *a, ...) __attribute__((format(printf, 1, 2))); // no-error
+
+void b(char *a, _Float16 b) __attribute__((format(printf, 1, 2))); // expected-warning {{GCC requires a function with the 'format' attribute to be variadic}}
+
+void call_no_default_promotion(void) {
+ a("%f", (_Float16)1.0); // expected-warning{{format specifies type 'double' but the argument has type '_Float16'}}
+ b("%f", (_Float16)1.0); // expected-warning{{format specifies type 'double' but the argument has type '_Float16'}}
+}
diff --git a/clang/test/SemaCXX/attr-format-Float16.cpp b/clang/test/SemaCXX/attr-format-Float16.cpp
new file mode 100644
index 0000000..c61611d
--- /dev/null
+++ b/clang/test/SemaCXX/attr-format-Float16.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -triple i686-linux-pc -target-feature +sse2 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-linux-pc %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple spir-unknown-unknown %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple armv7a-linux-gnu %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple aarch64-linux-gnu %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple riscv32 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple riscv64 %s
+
+template <typename... Args>
+__attribute__((format(printf, 1, 2)))
+void format(const char *fmt, Args &&...args); // expected-warning{{GCC requires a function with the 'format' attribute to be variadic}}
+
+template<typename... Args>
+__attribute__((format(scanf, 1, 2)))
+int scan(const char *fmt, Args &&...args); // expected-warning{{GCC requires a function with the 'format' attribute to be variadic}}
+
+void do_format() {
+ format("%f", (_Float16)123.f); // expected-warning{{format specifies type 'double' but the argument has type '_Float16'}}
+
+ _Float16 Float16;
+ scan("%f", &Float16); // expected-warning{{format specifies type 'float *' but the argument has type '_Float16 *'}}
+ scan("%lf", &Float16); // expected-warning{{format specifies type 'double *' but the argument has type '_Float16 *'}}
+ scan("%Lf", &Float16); // expected-warning{{format specifies type 'long double *' but the argument has type '_Float16 *'}}
+}
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 881993e..25ef5c6 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -26708,6 +26708,8 @@ TEST_F(FormatTest, PPBranchesInBracedInit) {
TEST_F(FormatTest, StreamOutputOperator) {
verifyFormat("std::cout << \"foo\" << \"bar\" << baz;");
+ verifyFormat("std::cout << \"foo\\n\"\n"
+ " << \"bar\";");
}
TEST_F(FormatTest, BreakAdjacentStringLiterals) {
diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp
index 2cafc04..decc078 100644
--- a/clang/unittests/Format/TokenAnnotatorTest.cpp
+++ b/clang/unittests/Format/TokenAnnotatorTest.cpp
@@ -2499,6 +2499,15 @@ TEST_F(TokenAnnotatorTest, BraceKind) {
EXPECT_BRACE_KIND(Tokens[6], BK_Block);
}
+TEST_F(TokenAnnotatorTest, StreamOperator) {
+ auto Tokens = annotate("\"foo\\n\" << aux << \"foo\\n\" << \"foo\";");
+ ASSERT_EQ(Tokens.size(), 9u) << Tokens;
+ EXPECT_FALSE(Tokens[1]->MustBreakBefore);
+ EXPECT_FALSE(Tokens[3]->MustBreakBefore);
+ // Only break between string literals if the former ends with \n.
+ EXPECT_TRUE(Tokens[5]->MustBreakBefore);
+}
+
} // namespace
} // namespace format
} // namespace clang