.git-blame-ignore-revs
@@ -67,3 +67,6 @@ f6d557ee34b6bbdb1dc32f29e34b4a4a8ad35e81
# [libc++] Rename _LIBCPP_INLINE_VISIBILITY to _LIBCPP_HIDE_FROM_ABI # [libc++] Rename _LIBCPP_INLINE_VISIBILITY to _LIBCPP_HIDE_FROM_ABI
4c198542226223f6a5c5511a1f89b37d15ee10b9 4c198542226223f6a5c5511a1f89b37d15ee10b9
+
+# [libc++] Replace uses of _VSTD:: by std:: (#74331)
+77a00c0d546cd4aa8311b5b9031ae9ea8cdb050c
.github/CODEOWNERS
@@ -33,26 +33,42 @@
/lldb/ @JDevlieghere /lldb/ @JDevlieghere
-/mlir/include/mlir/Interfaces/TilingInterface.* @MaheshRavishankar+# Linalg in MLIR.
+/mlir/include/mlir/Dialect/Linalg @dcaballe @nicolasvasilache
+/mlir/lib/Dialect/Linalg @dcaballe @nicolasvasilache
-/mlir/lib/Dialect/Linalg/Transforms/DecomposeLinalgOps.cpp @MaheshRavishankar+# Vector in MLIR.
-/mlir/lib/Dialect/Linalg/Transforms/DropUnitDims.cpp @MaheshRavishankar+/mlir/**/*AMX* @dcaballe
-/mlir/lib/Dialect/Linalg/Transforms/ElementwiseOpFusion.cpp @MaheshRavishankar+/mlir/**/*Neon* @banach-space @dcaballe @nicolasvasilache
-/mlir/lib/Dialect/MemRef/Transforms/EmulateNarrowType.cpp @MaheshRavishankar+/mlir/**/*SME* @banach-space @dcaballe @nicolasvasilache
-/mlir/lib/Dialect/Vector/Transforms/VectorEmulateNarrowType.cpp @MaheshRavishankar+/mlir/**/*SVE* @banach-space @dcaballe @nicolasvasilache
-/mlir/lib/Interfaces/TilingInterface.* @MaheshRavishankar+/mlir/**/*VectorInterfaces* @dcaballe @nicolasvasilache
+/mlir/**/*VectorToSCF* @banach-space @dcaballe @nicolasvasilache
+/mlir/**/*VectorToLLVM* @banach-space @dcaballe @nicolasvasilache
+/mlir/**/*X86Vector* @dcaballe @nicolasvasilache
+/mlir/include/mlir/Dialect/Vector @dcaballe @nicolasvasilache
+/mlir/lib/Dialect/Vector @dcaballe @nicolasvasilache
+
+/mlir/include/mlir/Interfaces/TilingInterface.* @MaheshRavishankar @nicolasvasilache
+
+/mlir/lib/Dialect/Linalg/Transforms/DecomposeLinalgOps.cpp @MaheshRavishankar @nicolasvasilache
+/mlir/lib/Dialect/Linalg/Transforms/DropUnitDims.cpp @MaheshRavishankar @nicolasvasilache
+/mlir/lib/Dialect/Linalg/Transforms/ElementwiseOpFusion.cpp @MaheshRavishankar @nicolasvasilache
+/mlir/lib/Dialect/MemRef/Transforms/EmulateNarrowType.cpp @MaheshRavishankar @nicolasvasilache
+/mlir/lib/Dialect/Vector/Transforms/VectorEmulateNarrowType.cpp @MaheshRavishankar @nicolasvasilache
+/mlir/lib/Interfaces/TilingInterface.* @MaheshRavishankar @nicolasvasilache
/mlir/**/*EmulateNarrowType* @hanhanW /mlir/**/*EmulateNarrowType* @hanhanW
-/mlir/lib/Dialect/Linalg/Transforms/DataLayoutPropagation.cpp @hanhanW+/mlir/lib/Dialect/Linalg/Transforms/DataLayoutPropagation.cpp @hanhanW @nicolasvasilache
-/mlir/lib/Dialect/Linalg/Transforms/Transforms.cpp @hanhanW+/mlir/lib/Dialect/Linalg/Transforms/Transforms.cpp @hanhanW @nicolasvasilache
-/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp @hanhanW+/mlir/lib/Dialect/Linalg/Transforms/Vectorization.cpp @hanhanW @nicolasvasilache
-/mlir/lib/Dialect/Tensor/IR/TensorTilingInterfaceImpl.cpp @hanhanW+/mlir/lib/Dialect/Tensor/IR/TensorTilingInterfaceImpl.cpp @hanhanW @nicolasvasilache
-/mlir/lib/Dialect/Tensor/Transforms/FoldIntoPackAndUnpackPatterns.cpp @hanhanW+/mlir/lib/Dialect/Tensor/Transforms/FoldIntoPackAndUnpackPatterns.cpp @hanhanW @nicolasvasilache
-/mlir/lib/Dialect/Vector/Transforms/* @hanhanW+/mlir/lib/Dialect/Vector/Transforms/* @hanhanW @nicolasvasilache
# Transform Dialect in MLIR. # Transform Dialect in MLIR.
-/mlir/include/mlir/Dialect/Transform/* @ftynse+/mlir/include/mlir/Dialect/Transform/* @ftynse @nicolasvasilache
-/mlir/lib/Dialect/Transform/* @ftynse+/mlir/lib/Dialect/Transform/* @ftynse @nicolasvasilache
# SPIR-V in MLIR. # SPIR-V in MLIR.
/mlir/**/SPIRV/ @antiagainst @kuhar /mlir/**/SPIRV/ @antiagainst @kuhar
.github/workflows/llvm-project-tests.yml
@@ -10,6 +10,11 @@ on:
required: false required: false
projects: projects:
required: false required: false
+ extra_cmake_args:
+ required: false
+ os_list:
+ required: false
+ default: '["ubuntu-latest", "windows-2019", "macOS-11"]'
workflow_call: workflow_call:
inputs: inputs:
build_target: build_target:
@@ -20,6 +25,19 @@ on:
required: true required: true
type: string type: string
+ extra_cmake_args:
+ required: false
+ type: string
+
+ os_list:
+ required: false
+ type: string
+ # Use windows-2019 due to:
+ # https://developercommunity.visualstudio.com/t/Prev-Issue---with-__assume-isnan-/1597317
+ # We're using a specific version of macOS due to:
+ # https://github.com/actions/virtual-environments/issues/5900
+ default: '["ubuntu-latest", "windows-2019", "macOS-11"]'
+
concurrency: concurrency:
# Skip intermediate builds: always. # Skip intermediate builds: always.
# Cancel intermediate builds: only if it is a pull request build. # Cancel intermediate builds: only if it is a pull request build.
@@ -35,14 +53,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
- os:+ os: ${{ fromJSON(inputs.os_list) }}
- - ubuntu-latest
- # Use windows-2019 due to:
- # https://developercommunity.visualstudio.com/t/Prev-Issue---with-__assume-isnan-/1597317
- - windows-2019
- # We're using a specific version of macOS due to:
- # https://github.com/actions/virtual-environments/issues/5900
- - macOS-11
steps: steps:
- name: Setup Windows - name: Setup Windows
if: startsWith(matrix.os, 'windows') if: startsWith(matrix.os, 'windows')
@@ -85,7 +96,7 @@ jobs:
# This should be a no-op for non-mac OSes # This should be a no-op for non-mac OSes
PKG_CONFIG_PATH: /usr/local/Homebrew/Library/Homebrew/os/mac/pkgconfig//12 PKG_CONFIG_PATH: /usr/local/Homebrew/Library/Homebrew/os/mac/pkgconfig//12
with: with:
- cmake_args: '-GNinja -DLLVM_ENABLE_PROJECTS="${{ inputs.projects }}" -DCMAKE_BUILD_TYPE=Release -DLLDB_INCLUDE_TESTS=OFF -DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache'+ cmake_args: '-GNinja -DLLVM_ENABLE_PROJECTS="${{ inputs.projects }}" -DCMAKE_BUILD_TYPE=Release -DLLDB_INCLUDE_TESTS=OFF -DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache ${{ inputs.extra_cmake_args }}'
build_target: '${{ inputs.build_target }}' build_target: '${{ inputs.build_target }}'
- name: Build and Test libclc - name: Build and Test libclc
.github/workflows/spirv-tests.yml
@@ -0,0 +1,29 @@
+name: SPIR-V Tests
+
+permissions:
+ contents: read
+
+on:
+ workflow_dispatch:
+ pull_request:
+ paths:
+ - 'llvm/lib/Target/SPIRV/**'
+ - 'llvm/test/CodeGen/SPIRV/**'
+ - '.github/workflows/spirv-tests.yml'
+
+concurrency:
+ # Skip intermediate builds: always.
+ # Cancel intermediate builds: only if it is a pull request build.
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
+
+jobs:
+ check_spirv:
+ if: github.repository_owner == 'llvm'
+ name: Test SPIR-V
+ uses: ./.github/workflows/llvm-project-tests.yml
+ with:
+ build_target: check-llvm-codegen-spirv
+ projects:
+ extra_cmake_args: '-DLLVM_TARGETS_TO_BUILD="" -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD="SPIRV"'
+ os_list: '["ubuntu-latest"]'
.mailmap
@@ -33,6 +33,8 @@
<qiucofan@cn.ibm.com> <qiucf@cn.ibm.com> <qiucofan@cn.ibm.com> <qiucf@cn.ibm.com>
<rnk@google.com> <reid@kleckner.net> <rnk@google.com> <reid@kleckner.net>
<thakis@chromium.org> <nicolasweber@gmx.de> <thakis@chromium.org> <nicolasweber@gmx.de>
+Jianjian GUAN <jacquesguan@me.com>
+Jianjian GUAN <jacquesguan@me.com> <Jianjian.Guan@streamcomputing.com>
Jon Roelofs <jonathan_roelofs@apple.com> <jonathan@codesourcery.com> Jon Roelofs <jonathan_roelofs@apple.com> <jonathan@codesourcery.com>
Jon Roelofs <jonathan_roelofs@apple.com> <jroelofs@jroelofs.com> Jon Roelofs <jonathan_roelofs@apple.com> <jroelofs@jroelofs.com>
Jonathan Thackray <jonathan.thackray@arm.com> <jthackray@users.noreply.github.com> Jonathan Thackray <jonathan.thackray@arm.com> <jthackray@users.noreply.github.com>
clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp
@@ -133,6 +133,21 @@ UnusedReturnValueCheck::UnusedReturnValueCheck(llvm::StringRef Name,
"::boost::system::error_code"))), "::boost::system::error_code"))),
AllowCastToVoid(Options.get("AllowCastToVoid", false)) {} AllowCastToVoid(Options.get("AllowCastToVoid", false)) {}
+UnusedReturnValueCheck::UnusedReturnValueCheck(llvm::StringRef Name,
+ ClangTidyContext *Context,
+ std::string CheckedFunctions)
+ : UnusedReturnValueCheck(Name, Context, std::move(CheckedFunctions), {},
+ false) {}
+
+UnusedReturnValueCheck::UnusedReturnValueCheck(
+ llvm::StringRef Name, ClangTidyContext *Context,
+ std::string CheckedFunctions, std::vector<StringRef> CheckedReturnTypes,
+ bool AllowCastToVoid)
+ : ClangTidyCheck(Name, Context),
+ CheckedFunctions(std::move(CheckedFunctions)),
+ CheckedReturnTypes(std::move(CheckedReturnTypes)),
+ AllowCastToVoid(AllowCastToVoid) {}
+
void UnusedReturnValueCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { void UnusedReturnValueCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "CheckedFunctions", CheckedFunctions); Options.store(Opts, "CheckedFunctions", CheckedFunctions);
Options.store(Opts, "CheckedReturnTypes", Options.store(Opts, "CheckedReturnTypes",
clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.h
@@ -31,7 +31,15 @@ public:
private: private:
std::string CheckedFunctions; std::string CheckedFunctions;
const std::vector<StringRef> CheckedReturnTypes; const std::vector<StringRef> CheckedReturnTypes;
- const bool AllowCastToVoid;+
+protected:
+ UnusedReturnValueCheck(StringRef Name, ClangTidyContext *Context,
+ std::string CheckedFunctions);
+ UnusedReturnValueCheck(StringRef Name, ClangTidyContext *Context,
+ std::string CheckedFunctions,
+ std::vector<StringRef> CheckedReturnTypes,
+ bool AllowCastToVoid);
+ bool AllowCastToVoid;
}; };
} // namespace clang::tidy::bugprone } // namespace clang::tidy::bugprone
clang-tools-extra/clang-tidy/hicpp/CMakeLists.txt
@@ -6,6 +6,7 @@ set(LLVM_LINK_COMPONENTS
add_clang_library(clangTidyHICPPModule add_clang_library(clangTidyHICPPModule
ExceptionBaseclassCheck.cpp ExceptionBaseclassCheck.cpp
HICPPTidyModule.cpp HICPPTidyModule.cpp
+ IgnoredRemoveResultCheck.cpp
MultiwayPathsCoveredCheck.cpp MultiwayPathsCoveredCheck.cpp
NoAssemblerCheck.cpp NoAssemblerCheck.cpp
SignedBitwiseCheck.cpp SignedBitwiseCheck.cpp
clang-tools-extra/clang-tidy/hicpp/HICPPTidyModule.cpp
@@ -37,6 +37,7 @@
#include "../readability/NamedParameterCheck.h" #include "../readability/NamedParameterCheck.h"
#include "../readability/UppercaseLiteralSuffixCheck.h" #include "../readability/UppercaseLiteralSuffixCheck.h"
#include "ExceptionBaseclassCheck.h" #include "ExceptionBaseclassCheck.h"
+#include "IgnoredRemoveResultCheck.h"
#include "MultiwayPathsCoveredCheck.h" #include "MultiwayPathsCoveredCheck.h"
#include "NoAssemblerCheck.h" #include "NoAssemblerCheck.h"
#include "SignedBitwiseCheck.h" #include "SignedBitwiseCheck.h"
@@ -57,6 +58,8 @@ public:
"hicpp-deprecated-headers"); "hicpp-deprecated-headers");
CheckFactories.registerCheck<ExceptionBaseclassCheck>( CheckFactories.registerCheck<ExceptionBaseclassCheck>(
"hicpp-exception-baseclass"); "hicpp-exception-baseclass");
+ CheckFactories.registerCheck<IgnoredRemoveResultCheck>(
+ "hicpp-ignored-remove-result");
CheckFactories.registerCheck<MultiwayPathsCoveredCheck>( CheckFactories.registerCheck<MultiwayPathsCoveredCheck>(
"hicpp-multiway-paths-covered"); "hicpp-multiway-paths-covered");
CheckFactories.registerCheck<SignedBitwiseCheck>("hicpp-signed-bitwise"); CheckFactories.registerCheck<SignedBitwiseCheck>("hicpp-signed-bitwise");
clang-tools-extra/clang-tidy/hicpp/IgnoredRemoveResultCheck.cpp
@@ -0,0 +1,28 @@
+//===--- IgnoredRemoveResultCheck.cpp - clang-tidy ------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "IgnoredRemoveResultCheck.h"
+
+namespace clang::tidy::hicpp {
+
+IgnoredRemoveResultCheck::IgnoredRemoveResultCheck(llvm::StringRef Name,
+ ClangTidyContext *Context)
+ : UnusedReturnValueCheck(Name, Context,
+ "::std::remove;"
+ "::std::remove_if;"
+ "::std::unique") {
+ // The constructor for ClangTidyCheck needs to have been called
+ // before we can access options via Options.get().
+ AllowCastToVoid = Options.get("AllowCastToVoid", true);
+}
+
+void IgnoredRemoveResultCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "AllowCastToVoid", AllowCastToVoid);
+}
+
+} // namespace clang::tidy::hicpp
clang-tools-extra/clang-tidy/hicpp/IgnoredRemoveResultCheck.h
@@ -0,0 +1,29 @@
+//===--- IgnoredRemoveResultCheck.h - clang-tidy ----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_HICPP_IGNOREDREMOVERESULTCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_HICPP_IGNOREDREMOVERESULTCHECK_H
+
+#include "../bugprone/UnusedReturnValueCheck.h"
+
+namespace clang::tidy::hicpp {
+
+/// Ensure that the result of std::remove, std::remove_if and std::unique
+/// are not ignored according to rule 17.5.1.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/hicpp/ignored-remove-result.html
+class IgnoredRemoveResultCheck : public bugprone::UnusedReturnValueCheck {
+public:
+ IgnoredRemoveResultCheck(StringRef Name, ClangTidyContext *Context);
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+};
+
+} // namespace clang::tidy::hicpp
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_HICPP_IGNOREDREMOVERESULTCHECK_H
clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp
@@ -15,6 +15,7 @@
#include "clang/AST/Decl.h" #include "clang/AST/Decl.h"
#include "clang/Basic/Diagnostic.h" #include "clang/Basic/Diagnostic.h"
#include <optional> #include <optional>
+#include <utility>
namespace clang::tidy::performance { namespace clang::tidy::performance {
namespace { namespace {
@@ -263,19 +264,25 @@ void UnnecessaryCopyInitialization::registerMatchers(MatchFinder *Finder) {
void UnnecessaryCopyInitialization::check( void UnnecessaryCopyInitialization::check(
const MatchFinder::MatchResult &Result) { const MatchFinder::MatchResult &Result) {
- const auto *NewVar = Result.Nodes.getNodeAs<VarDecl>("newVarDecl");+ const auto &NewVar = *Result.Nodes.getNodeAs<VarDecl>("newVarDecl");
+ const auto &BlockStmt = *Result.Nodes.getNodeAs<Stmt>("blockStmt");
+ const auto &VarDeclStmt = *Result.Nodes.getNodeAs<DeclStmt>("declStmt");
+ // Do not propose fixes if the DeclStmt has multiple VarDecls or in
+ // macros since we cannot place them correctly.
+ const bool IssueFix =
+ VarDeclStmt.isSingleDecl() && !NewVar.getLocation().isMacroID();
+ const bool IsVarUnused = isVariableUnused(NewVar, BlockStmt, *Result.Context);
+ const bool IsVarOnlyUsedAsConst =
+ isOnlyUsedAsConst(NewVar, BlockStmt, *Result.Context);
+ const CheckContext Context{
+ NewVar, BlockStmt, VarDeclStmt, *Result.Context,
+ IssueFix, IsVarUnused, IsVarOnlyUsedAsConst};
const auto *OldVar = Result.Nodes.getNodeAs<VarDecl>(OldVarDeclId); const auto *OldVar = Result.Nodes.getNodeAs<VarDecl>(OldVarDeclId);
const auto *ObjectArg = Result.Nodes.getNodeAs<VarDecl>(ObjectArgId); const auto *ObjectArg = Result.Nodes.getNodeAs<VarDecl>(ObjectArgId);
- const auto *BlockStmt = Result.Nodes.getNodeAs<Stmt>("blockStmt");
const auto *CtorCall = Result.Nodes.getNodeAs<CXXConstructExpr>("ctorCall"); const auto *CtorCall = Result.Nodes.getNodeAs<CXXConstructExpr>("ctorCall");
- const auto *Stmt = Result.Nodes.getNodeAs<DeclStmt>("declStmt");
TraversalKindScope RAII(*Result.Context, TK_AsIs); TraversalKindScope RAII(*Result.Context, TK_AsIs);
- // Do not propose fixes if the DeclStmt has multiple VarDecls or in macros
- // since we cannot place them correctly.
- bool IssueFix = Stmt->isSingleDecl() && !NewVar->getLocation().isMacroID();
-
// A constructor that looks like T(const T& t, bool arg = false) counts as a // A constructor that looks like T(const T& t, bool arg = false) counts as a
// copy only when it is called with default arguments for the arguments after // copy only when it is called with default arguments for the arguments after
// the first. // the first.
@@ -289,74 +296,71 @@ void UnnecessaryCopyInitialization::check(
// instantiations where the types differ and rely on implicit conversion would // instantiations where the types differ and rely on implicit conversion would
// no longer compile if we switched to a reference. // no longer compile if we switched to a reference.
if (differentReplacedTemplateParams( if (differentReplacedTemplateParams(
- NewVar->getType(), constructorArgumentType(OldVar, Result.Nodes),+ Context.Var.getType(), constructorArgumentType(OldVar, Result.Nodes),
*Result.Context)) *Result.Context))
return; return;
if (OldVar == nullptr) { if (OldVar == nullptr) {
- handleCopyFromMethodReturn(*NewVar, *BlockStmt, *Stmt, IssueFix, ObjectArg,+ // `auto NewVar = functionCall();`
- *Result.Context);+ handleCopyFromMethodReturn(Context, ObjectArg);
} else { } else {
- handleCopyFromLocalVar(*NewVar, *OldVar, *BlockStmt, *Stmt, IssueFix,+ // `auto NewVar = OldVar;`
- *Result.Context);+ handleCopyFromLocalVar(Context, *OldVar);
} }
} }
void UnnecessaryCopyInitialization::handleCopyFromMethodReturn( void UnnecessaryCopyInitialization::handleCopyFromMethodReturn(
- const VarDecl &Var, const Stmt &BlockStmt, const DeclStmt &Stmt,+ const CheckContext &Ctx, const VarDecl *ObjectArg) {
- bool IssueFix, const VarDecl *ObjectArg, ASTContext &Context) {+ bool IsConstQualified = Ctx.Var.getType().isConstQualified();
- bool IsConstQualified = Var.getType().isConstQualified();+ if (!IsConstQualified && !Ctx.IsVarOnlyUsedAsConst)
- if (!IsConstQualified && !isOnlyUsedAsConst(Var, BlockStmt, Context))
return; return;
if (ObjectArg != nullptr && if (ObjectArg != nullptr &&
- !isInitializingVariableImmutable(*ObjectArg, BlockStmt, Context,+ !isInitializingVariableImmutable(*ObjectArg, Ctx.BlockStmt, Ctx.ASTCtx,
ExcludedContainerTypes)) ExcludedContainerTypes))
return; return;
- if (isVariableUnused(Var, BlockStmt, Context)) {+ diagnoseCopyFromMethodReturn(Ctx);
- auto Diagnostic =
- diag(Var.getLocation(),
- "the %select{|const qualified }0variable %1 is copy-constructed "
- "from a const reference but is never used; consider "
- "removing the statement")
- << IsConstQualified << &Var;
- if (IssueFix)
- recordRemoval(Stmt, Context, Diagnostic);
- } else {
- auto Diagnostic =
- diag(Var.getLocation(),
- "the %select{|const qualified }0variable %1 is copy-constructed "
- "from a const reference%select{ but is only used as const "
- "reference|}0; consider making it a const reference")
- << IsConstQualified << &Var;
- if (IssueFix)
- recordFixes(Var, Context, Diagnostic);
- }
} }
void UnnecessaryCopyInitialization::handleCopyFromLocalVar( void UnnecessaryCopyInitialization::handleCopyFromLocalVar(
- const VarDecl &NewVar, const VarDecl &OldVar, const Stmt &BlockStmt,+ const CheckContext &Ctx, const VarDecl &OldVar) {
- const DeclStmt &Stmt, bool IssueFix, ASTContext &Context) {+ if (!Ctx.IsVarOnlyUsedAsConst ||
- if (!isOnlyUsedAsConst(NewVar, BlockStmt, Context) ||+ !isInitializingVariableImmutable(OldVar, Ctx.BlockStmt, Ctx.ASTCtx,
- !isInitializingVariableImmutable(OldVar, BlockStmt, Context,
ExcludedContainerTypes)) ExcludedContainerTypes))
return; return;
+ diagnoseCopyFromLocalVar(Ctx, OldVar);
+}
- if (isVariableUnused(NewVar, BlockStmt, Context)) {+void UnnecessaryCopyInitialization::diagnoseCopyFromMethodReturn(
- auto Diagnostic = diag(NewVar.getLocation(),+ const CheckContext &Ctx) {
- "local copy %0 of the variable %1 is never modified "+ auto Diagnostic =
- "and never used; "+ diag(Ctx.Var.getLocation(),
- "consider removing the statement")+ "the %select{|const qualified }0variable %1 is "
- << &NewVar << &OldVar;+ "copy-constructed "
- if (IssueFix)+ "from a const reference%select{%select{ but is only used as const "
- recordRemoval(Stmt, Context, Diagnostic);+ "reference|}0| but is never used}2; consider "
- } else {+ "%select{making it a const reference|removing the statement}2")
- auto Diagnostic =+ << Ctx.Var.getType().isConstQualified() << &Ctx.Var << Ctx.IsVarUnused;
- diag(NewVar.getLocation(),+ maybeIssueFixes(Ctx, Diagnostic);
- "local copy %0 of the variable %1 is never modified; "+}
- "consider avoiding the copy")+
- << &NewVar << &OldVar;+void UnnecessaryCopyInitialization::diagnoseCopyFromLocalVar(
- if (IssueFix)+ const CheckContext &Ctx, const VarDecl &OldVar) {
- recordFixes(NewVar, Context, Diagnostic);+ auto Diagnostic =
+ diag(Ctx.Var.getLocation(),
+ "local copy %1 of the variable %0 is never modified%select{"
+ "| and never used}2; consider %select{avoiding the copy|removing "
+ "the statement}2")
+ << &OldVar << &Ctx.Var << Ctx.IsVarUnused;
+ maybeIssueFixes(Ctx, Diagnostic);
+}
+
+void UnnecessaryCopyInitialization::maybeIssueFixes(
+ const CheckContext &Ctx, DiagnosticBuilder &Diagnostic) {
+ if (Ctx.IssueFix) {
+ if (Ctx.IsVarUnused)
+ recordRemoval(Ctx.VarDeclStmt, Ctx.ASTCtx, Diagnostic);
+ else
+ recordFixes(Ctx.Var, Ctx.ASTCtx, Diagnostic);
} }
} }
clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.h
@@ -32,14 +32,32 @@ public:
void check(const ast_matchers::MatchFinder::MatchResult &Result) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+protected:
+ // A helper to manipulate the state common to
+ // `CopyFromMethodReturn` and `CopyFromLocalVar`.
+ struct CheckContext {
+ const VarDecl &Var;
+ const Stmt &BlockStmt;
+ const DeclStmt &VarDeclStmt;
+ clang::ASTContext &ASTCtx;
+ const bool IssueFix;
+ const bool IsVarUnused;
+ const bool IsVarOnlyUsedAsConst;
+ };
+
+ // Create diagnostics. These are virtual so that derived classes can change
+ // behaviour.
+ virtual void diagnoseCopyFromMethodReturn(const CheckContext &Ctx);
+ virtual void diagnoseCopyFromLocalVar(const CheckContext &Ctx,
+ const VarDecl &OldVar);
+
private: private:
- void handleCopyFromMethodReturn(const VarDecl &Var, const Stmt &BlockStmt,+ void handleCopyFromMethodReturn(const CheckContext &Ctx,
- const DeclStmt &Stmt, bool IssueFix,+ const VarDecl *ObjectArg);
- const VarDecl *ObjectArg,+ void handleCopyFromLocalVar(const CheckContext &Ctx, const VarDecl &OldVar);
- ASTContext &Context);+
- void handleCopyFromLocalVar(const VarDecl &NewVar, const VarDecl &OldVar,+ void maybeIssueFixes(const CheckContext &Ctx, DiagnosticBuilder &Diagnostic);
- const Stmt &BlockStmt, const DeclStmt &Stmt,+
- bool IssueFix, ASTContext &Context);
const std::vector<StringRef> AllowedTypes; const std::vector<StringRef> AllowedTypes;
const std::vector<StringRef> ExcludedContainerTypes; const std::vector<StringRef> ExcludedContainerTypes;
}; };
clang-tools-extra/docs/ReleaseNotes.rst
@@ -174,6 +174,12 @@ New checks
Flags coroutines that suspend while a lock guard is in scope at the Flags coroutines that suspend while a lock guard is in scope at the
suspension point. suspension point.
+- New :doc:`hicpp-ignored-remove-result
+ <clang-tidy/checks/hicpp/ignored-remove-result>` check.
+
+ Ensure that the result of ``std::remove``, ``std::remove_if`` and
+ ``std::unique`` are not ignored according to rule 17.5.1.
+
- New :doc:`misc-coroutine-hostile-raii - New :doc:`misc-coroutine-hostile-raii
<clang-tidy/checks/misc/coroutine-hostile-raii>` check. <clang-tidy/checks/misc/coroutine-hostile-raii>` check.
clang-tools-extra/docs/clang-tidy/checks/hicpp/ignored-remove-result.rst
@@ -0,0 +1,24 @@
+.. title:: clang-tidy - hicpp-ignored-remove-result
+
+hicpp-ignored-remove-result
+===========================
+
+Ensure that the result of ``std::remove``, ``std::remove_if`` and ``std::unique``
+are not ignored according to
+`rule 17.5.1 <https://www.perforce.com/resources/qac/high-integrity-cpp-coding-standard/standard-library>`_.
+
+The mutating algorithms ``std::remove``, ``std::remove_if`` and both overloads
+of ``std::unique`` operate by swapping or moving elements of the range they are
+operating over. On completion, they return an iterator to the last valid
+element. In the majority of cases the correct behavior is to use this result as
+the first operand in a call to ``std::erase``.
+
+This check is a subset of :doc:`bugprone-unused-return-value <../bugprone/unused-return-value>`
+and depending on used options it can be superfluous to enable both checks.
+
+Options
+-------
+
+.. option:: AllowCastToVoid
+
+ Controls whether casting return values to ``void`` is permitted. Default: `true`.
clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -226,6 +226,7 @@ Clang-Tidy Checks
:doc:`google-runtime-operator <google/runtime-operator>`, :doc:`google-runtime-operator <google/runtime-operator>`,
:doc:`google-upgrade-googletest-case <google/upgrade-googletest-case>`, "Yes" :doc:`google-upgrade-googletest-case <google/upgrade-googletest-case>`, "Yes"
:doc:`hicpp-exception-baseclass <hicpp/exception-baseclass>`, :doc:`hicpp-exception-baseclass <hicpp/exception-baseclass>`,
+ :doc:`hicpp-ignored-remove-result <hicpp/ignored-remove-result>`,
:doc:`hicpp-multiway-paths-covered <hicpp/multiway-paths-covered>`, :doc:`hicpp-multiway-paths-covered <hicpp/multiway-paths-covered>`,
:doc:`hicpp-no-assembler <hicpp/no-assembler>`, :doc:`hicpp-no-assembler <hicpp/no-assembler>`,
:doc:`hicpp-signed-bitwise <hicpp/signed-bitwise>`, :doc:`hicpp-signed-bitwise <hicpp/signed-bitwise>`,
clang-tools-extra/test/clang-tidy/checkers/hicpp/ignored-remove-result.cpp
@@ -0,0 +1,66 @@
+// RUN: %check_clang_tidy %s hicpp-ignored-remove-result %t
+// RUN: %check_clang_tidy -check-suffixes=NOCAST %s hicpp-ignored-remove-result %t -- -config='{CheckOptions: {hicpp-ignored-remove-result.AllowCastToVoid: false}}'
+
+namespace std {
+
+template <typename ForwardIt, typename T>
+ForwardIt remove(ForwardIt, ForwardIt, const T &);
+
+template <typename ForwardIt, typename UnaryPredicate>
+ForwardIt remove_if(ForwardIt, ForwardIt, UnaryPredicate);
+
+template <typename ForwardIt>
+ForwardIt unique(ForwardIt, ForwardIt);
+
+template <class InputIt, class T>
+InputIt find(InputIt, InputIt, const T&);
+
+class error_code {
+};
+
+} // namespace std
+
+std::error_code errorFunc() {
+ return std::error_code();
+}
+
+void warning() {
+ std::remove(nullptr, nullptr, 1);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: the value returned by this function should not be disregarded; neglecting it may lead to errors
+ // CHECK-MESSAGES: [[@LINE-2]]:3: note: cast the expression to void to silence this warning
+ // CHECK-MESSAGES-NOCAST: [[@LINE-3]]:3: warning: the value returned by this function should not be disregarded; neglecting it may lead to errors
+
+ std::remove_if(nullptr, nullptr, nullptr);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: the value returned by this function should not be disregarded; neglecting it may lead to errors
+ // CHECK-MESSAGES: [[@LINE-2]]:3: note: cast the expression to void to silence this warning
+ // CHECK-MESSAGES-NOCAST: [[@LINE-3]]:3: warning: the value returned by this function should not be disregarded; neglecting it may lead to errors
+
+ std::unique(nullptr, nullptr);
+ // CHECK-MESSAGES: [[@LINE-1]]:3: warning: the value returned by this function should not be disregarded; neglecting it may lead to errors
+ // CHECK-MESSAGES: [[@LINE-2]]:3: note: cast the expression to void to silence this warning
+ // CHECK-MESSAGES-NOCAST: [[@LINE-3]]:3: warning: the value returned by this function should not be disregarded; neglecting it may lead to errors
+}
+
+void optionalWarning() {
+ // No warning unless AllowCastToVoid=false
+ (void)std::remove(nullptr, nullptr, 1);
+ // CHECK-MESSAGES-NOCAST: [[@LINE-1]]:9: warning: the value returned by this function should not be disregarded; neglecting it may lead to errors
+}
+
+void noWarning() {
+
+ auto RemoveRetval = std::remove(nullptr, nullptr, 1);
+
+ auto RemoveIfRetval = std::remove_if(nullptr, nullptr, nullptr);
+
+ auto UniqueRetval = std::unique(nullptr, nullptr);
+
+ // Verify that other checks in the baseclass are not used.
+ // - no warning on std::find since the checker overrides
+ // bugprone-unused-return-value's checked functions.
+ std::find(nullptr, nullptr, 1);
+ // - no warning on return types since the checker disable
+ // bugprone-unused-return-value's checked return types.
+ errorFunc();
+ (void) errorFunc();
+}
clang/docs/LanguageExtensions.rst
@@ -1483,6 +1483,7 @@ Conditional ``explicit`` __cpp_conditional_explicit C++20
``using enum`` __cpp_using_enum C++20 C++03 ``using enum`` __cpp_using_enum C++20 C++03
``if consteval`` __cpp_if_consteval C++23 C++20 ``if consteval`` __cpp_if_consteval C++23 C++20
``static operator()`` __cpp_static_call_operator C++23 C++03 ``static operator()`` __cpp_static_call_operator C++23 C++03
+Attributes on Lambda-Expressions C++23 C++11
-------------------------------------- -------------------------------- ------------- ------------- -------------------------------------- -------------------------------- ------------- -------------
Designated initializers (N494) C99 C89 Designated initializers (N494) C99 C89
Array & element qualification (N2607) C23 C89 Array & element qualification (N2607) C23 C89
@@ -3866,6 +3867,30 @@ builtin function, and are named with a ``__opencl_`` prefix. The macros
and ``__OPENCL_MEMORY_SCOPE_SUB_GROUP`` are provided, with values and ``__OPENCL_MEMORY_SCOPE_SUB_GROUP`` are provided, with values
corresponding to the enumerators of OpenCL's ``memory_scope`` enumeration.) corresponding to the enumerators of OpenCL's ``memory_scope`` enumeration.)
+__scoped_atomic builtins
+------------------------
+
+Clang provides a set of atomics taking a memory scope argument. These atomics
+are identical to the standard GNU / GCC atomic builtins but taking an extra
+memory scope argument. These are designed to be a generic alternative to the
+``__opencl_atomic_*`` builtin functions for targets that support atomic memory
+scopes.
+
+Atomic memory scopes are designed to assist optimizations for systems with
+several levels of memory hierarchy like GPUs. The following memory scopes are
+currently supported:
+
+* ``__MEMORY_SCOPE_SYSTEM``
+* ``__MEMORY_SCOPE_DEVICE``
+* ``__MEMORY_SCOPE_WRKGRP``
+* ``__MEMORY_SCOPE_WVFRNT``
+* ``__MEMORY_SCOPE_SINGLE``
+
+This controls whether or not the atomic operation is ordered with respect to the
+whole system, the current device, an OpenCL workgroup, wavefront, or just a
+single thread. If these are used on a target that does not support atomic
+scopes, then they will behave exactly as the standard GNU atomic builtins.
+
Low-level ARM exclusive memory builtins Low-level ARM exclusive memory builtins
--------------------------------------- ---------------------------------------
clang/docs/ReleaseNotes.rst
@@ -156,6 +156,9 @@ C++23 Feature Support
support for this feature is still experimental, the feature test macro ``__cpp_explicit_this_parameter`` support for this feature is still experimental, the feature test macro ``__cpp_explicit_this_parameter``
was not set in this version. was not set in this version.
+- Added a separate warning to warn the use of attributes on lambdas as a C++23 extension
+ in previous language versions: ``-Wc++23-lambda-attributes``.
+
C++2c Feature Support C++2c Feature Support
^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^
@@ -201,6 +204,9 @@ C Language Changes
number of elements in the flexible array member. This information can improve number of elements in the flexible array member. This information can improve
the results of the array bound sanitizer and the the results of the array bound sanitizer and the
``__builtin_dynamic_object_size`` builtin. ``__builtin_dynamic_object_size`` builtin.
+- Enums will now be represented in TBAA metadata using their actual underlying
+ integer type. Previously they were treated as chars, which meant they could
+ alias with all other types.
C23 Feature Support C23 Feature Support
^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
@@ -353,6 +359,8 @@ Improvements to Clang's diagnostics
of a base class is not called in the constructor of its derived class. of a base class is not called in the constructor of its derived class.
- Clang no longer emits ``-Wmissing-variable-declarations`` for variables declared - Clang no longer emits ``-Wmissing-variable-declarations`` for variables declared
with the ``register`` storage class. with the ``register`` storage class.
+- Clang's ``-Wswitch-default`` flag now diagnoses whenever a ``switch`` statement
+ does not have a ``default`` label.
- Clang's ``-Wtautological-negation-compare`` flag now diagnoses logical - Clang's ``-Wtautological-negation-compare`` flag now diagnoses logical
tautologies like ``x && !x`` and ``!x || x`` in expressions. This also tautologies like ``x && !x`` and ``!x || x`` in expressions. This also
makes ``-Winfinite-recursion`` diagnose more cases. makes ``-Winfinite-recursion`` diagnose more cases.
@@ -651,6 +659,9 @@ Bug Fixes in This Version
- Fixed false positive error emitted by clang when performing qualified name - Fixed false positive error emitted by clang when performing qualified name
lookup and the current class instantiation has dependent bases. lookup and the current class instantiation has dependent bases.
Fixes (`#13826 <https://github.com/llvm/llvm-project/issues/13826>`_) Fixes (`#13826 <https://github.com/llvm/llvm-project/issues/13826>`_)
+- Fix a ``clang-17`` regression where a templated friend with constraints is not
+ properly applied when its parameters reference an enclosing non-template class.
+ Fixes (`#71595 <https://github.com/llvm/llvm-project/issues/71595>`_)
- Fix the name of the ifunc symbol emitted for multiversion functions declared with the - Fix the name of the ifunc symbol emitted for multiversion functions declared with the
``target_clones`` attribute. This addresses a linker error that would otherwise occur ``target_clones`` attribute. This addresses a linker error that would otherwise occur
when these functions are referenced from other TUs. when these functions are referenced from other TUs.
@@ -658,6 +669,12 @@ Bug Fixes in This Version
Fixes (`#64467 <https://github.com/llvm/llvm-project/issues/64467>`_) Fixes (`#64467 <https://github.com/llvm/llvm-project/issues/64467>`_)
- Clang's ``-Wchar-subscripts`` no longer warns on chars whose values are known non-negative constants. - Clang's ``-Wchar-subscripts`` no longer warns on chars whose values are known non-negative constants.
Fixes (`#18763 <https://github.com/llvm/llvm-project/issues/18763>`_) Fixes (`#18763 <https://github.com/llvm/llvm-project/issues/18763>`_)
+- Fix crash due to incorrectly allowing conversion functions in copy elision.
+ Fixes (`#39319 <https://github.com/llvm/llvm-project/issues/39319>`_) and
+ (`#60182 <https://github.com/llvm/llvm-project/issues/60182>`_) and
+ (`#62157 <https://github.com/llvm/llvm-project/issues/62157>`_) and
+ (`#64885 <https://github.com/llvm/llvm-project/issues/64885>`_) and
+ (`#65568 <https://github.com/llvm/llvm-project/issues/65568>`_)
Bug Fixes to Compiler Builtins Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -886,11 +903,17 @@ Arm and AArch64 Support
- New AArch64 asm constraints have been added for r8-r11(Uci) and r12-r15(Ucj). - New AArch64 asm constraints have been added for r8-r11(Uci) and r12-r15(Ucj).
- Support has been added for the following processors (-mcpu identifiers in parenthesis):+- Support has been added for the following processors (-mcpu identifiers in parenthesis):
+
+ For Arm:
+
+ * Cortex-M52 (cortex-m52).
+
+ For AArch64:
- * Arm Cortex-A520 (cortex-a520).+ * Cortex-A520 (cortex-a520).
- * Arm Cortex-A720 (cortex-a720).+ * Cortex-A720 (cortex-a720).
- * Arm Cortex-X4 (cortex-x4).+ * Cortex-X4 (cortex-x4).
Android Support Android Support
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
clang/include/clang/AST/Expr.h
@@ -6498,7 +6498,7 @@ public:
return cast<Expr>(SubExprs[ORDER_FAIL]); return cast<Expr>(SubExprs[ORDER_FAIL]);
} }
Expr *getVal2() const { Expr *getVal2() const {
- if (Op == AO__atomic_exchange)+ if (Op == AO__atomic_exchange || Op == AO__scoped_atomic_exchange)
return cast<Expr>(SubExprs[ORDER_FAIL]); return cast<Expr>(SubExprs[ORDER_FAIL]);
assert(NumSubExprs > VAL2); assert(NumSubExprs > VAL2);
return cast<Expr>(SubExprs[VAL2]); return cast<Expr>(SubExprs[VAL2]);
@@ -6539,7 +6539,9 @@ public:
getOp() == AO__opencl_atomic_compare_exchange_weak || getOp() == AO__opencl_atomic_compare_exchange_weak ||
getOp() == AO__hip_atomic_compare_exchange_weak || getOp() == AO__hip_atomic_compare_exchange_weak ||
getOp() == AO__atomic_compare_exchange || getOp() == AO__atomic_compare_exchange ||
- getOp() == AO__atomic_compare_exchange_n;+ getOp() == AO__atomic_compare_exchange_n ||
+ getOp() == AO__scoped_atomic_compare_exchange ||
+ getOp() == AO__scoped_atomic_compare_exchange_n;
} }
bool isOpenCL() const { bool isOpenCL() const {
@@ -6569,13 +6571,13 @@ public:
/// \return empty atomic scope model if the atomic op code does not have /// \return empty atomic scope model if the atomic op code does not have
/// scope operand. /// scope operand.
static std::unique_ptr<AtomicScopeModel> getScopeModel(AtomicOp Op) { static std::unique_ptr<AtomicScopeModel> getScopeModel(AtomicOp Op) {
- auto Kind =+ if (Op >= AO__opencl_atomic_load && Op <= AO__opencl_atomic_fetch_max)
- (Op >= AO__opencl_atomic_load && Op <= AO__opencl_atomic_fetch_max)+ return AtomicScopeModel::create(AtomicScopeModelKind::OpenCL);
- ? AtomicScopeModelKind::OpenCL+ else if (Op >= AO__hip_atomic_load && Op <= AO__hip_atomic_fetch_max)
- : (Op >= AO__hip_atomic_load && Op <= AO__hip_atomic_fetch_max)+ return AtomicScopeModel::create(AtomicScopeModelKind::HIP);
- ? AtomicScopeModelKind::HIP+ else if (Op >= AO__scoped_atomic_load && Op <= AO__scoped_atomic_fetch_max)
- : AtomicScopeModelKind::None;+ return AtomicScopeModel::create(AtomicScopeModelKind::Generic);
- return AtomicScopeModel::create(Kind);+ return AtomicScopeModel::create(AtomicScopeModelKind::None);
} }
/// Get atomic scope model. /// Get atomic scope model.
clang/include/clang/Basic/AttrDocs.td
@@ -2659,8 +2659,9 @@ An error will be given if:
- Specified values violate subtarget specifications; - Specified values violate subtarget specifications;
- Specified values are not compatible with values provided through other - Specified values are not compatible with values provided through other
attributes; attributes;
- - The AMDGPU target backend is unable to create machine code that can meet the+
- request.+The AMDGPU target backend will emit a warning whenever it is unable to
+create machine code that meets the request.
}]; }];
} }
clang/include/clang/Basic/Builtins.def
@@ -904,6 +904,32 @@ BUILTIN(__atomic_signal_fence, "vi", "n")
BUILTIN(__atomic_always_lock_free, "bzvCD*", "nE") BUILTIN(__atomic_always_lock_free, "bzvCD*", "nE")
BUILTIN(__atomic_is_lock_free, "bzvCD*", "nE") BUILTIN(__atomic_is_lock_free, "bzvCD*", "nE")
+// GNU atomic builtins with atomic scopes.
+ATOMIC_BUILTIN(__scoped_atomic_load, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_load_n, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_store, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_store_n, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_exchange, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_exchange_n, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_compare_exchange, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_compare_exchange_n, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_fetch_add, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_fetch_sub, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_fetch_and, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_fetch_or, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_fetch_xor, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_fetch_nand, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_add_fetch, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_sub_fetch, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_and_fetch, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_or_fetch, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_xor_fetch, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_max_fetch, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_min_fetch, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_nand_fetch, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_fetch_min, "v.", "t")
+ATOMIC_BUILTIN(__scoped_atomic_fetch_max, "v.", "t")
+
// OpenCL 2.0 atomic builtins. // OpenCL 2.0 atomic builtins.
ATOMIC_BUILTIN(__opencl_atomic_init, "v.", "t") ATOMIC_BUILTIN(__opencl_atomic_init, "v.", "t")
ATOMIC_BUILTIN(__opencl_atomic_load, "v.", "t") ATOMIC_BUILTIN(__opencl_atomic_load, "v.", "t")
clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -80,6 +80,7 @@ def remark_fe_backend_optimization_remark_analysis_aliasing : Remark<"%0; "
"the '__restrict__' qualifier with the independent array arguments. " "the '__restrict__' qualifier with the independent array arguments. "
"Erroneous results will occur if these options are incorrectly applied!">, "Erroneous results will occur if these options are incorrectly applied!">,
BackendInfo, InGroup<BackendOptimizationRemarkAnalysis>; BackendInfo, InGroup<BackendOptimizationRemarkAnalysis>;
+
def warn_fe_backend_optimization_failure : Warning<"%0">, BackendInfo, def warn_fe_backend_optimization_failure : Warning<"%0">, BackendInfo,
InGroup<BackendOptimizationFailure>, DefaultWarn; InGroup<BackendOptimizationFailure>, DefaultWarn;
def note_fe_backend_invalid_loc : Note<"could " def note_fe_backend_invalid_loc : Note<"could "
clang/include/clang/Basic/DiagnosticGroups.td
@@ -632,7 +632,7 @@ def ShadowAll : DiagGroup<"shadow-all", [Shadow, ShadowFieldInConstructor,
def Shorten64To32 : DiagGroup<"shorten-64-to-32">; def Shorten64To32 : DiagGroup<"shorten-64-to-32">;
def : DiagGroup<"sign-promo">; def : DiagGroup<"sign-promo">;
def SignCompare : DiagGroup<"sign-compare">; def SignCompare : DiagGroup<"sign-compare">;
-def : DiagGroup<"switch-default">;+def SwitchDefault : DiagGroup<"switch-default">;
def : DiagGroup<"synth">; def : DiagGroup<"synth">;
def SizeofArrayArgument : DiagGroup<"sizeof-array-argument">; def SizeofArrayArgument : DiagGroup<"sizeof-array-argument">;
def SizeofArrayDecay : DiagGroup<"sizeof-array-decay">; def SizeofArrayDecay : DiagGroup<"sizeof-array-decay">;
@@ -1126,6 +1126,8 @@ def FutureAttrs : DiagGroup<"future-attribute-extensions", [CXX14Attrs,
CXX17Attrs, CXX17Attrs,
CXX20Attrs]>; CXX20Attrs]>;
+def CXX23AttrsOnLambda : DiagGroup<"c++23-lambda-attributes">;
+
// A warning group for warnings about using C++11 features as extensions in // A warning group for warnings about using C++11 features as extensions in
// earlier C++ versions. // earlier C++ versions.
def CXX11 : DiagGroup<"c++11-extensions", [CXX11ExtraSemi, CXX11InlineNamespace, def CXX11 : DiagGroup<"c++11-extensions", [CXX11ExtraSemi, CXX11InlineNamespace,
@@ -1145,7 +1147,7 @@ def CXX20 : DiagGroup<"c++20-extensions", [CXX20Designator, CXX20Attrs]>;
// A warning group for warnings about using C++23 features as extensions in // A warning group for warnings about using C++23 features as extensions in
// earlier C++ versions. // earlier C++ versions.
-def CXX23 : DiagGroup<"c++23-extensions">;+def CXX23 : DiagGroup<"c++23-extensions", [CXX23AttrsOnLambda]>;
// A warning group for warnings about using C++26 features as extensions in // A warning group for warnings about using C++26 features as extensions in
// earlier C++ versions. // earlier C++ versions.
clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1035,7 +1035,7 @@ def err_capture_default_first : Error<
"capture default must be first">; "capture default must be first">;
def ext_decl_attrs_on_lambda : ExtWarn< def ext_decl_attrs_on_lambda : ExtWarn<
"%select{an attribute specifier sequence|%0}1 in this position " "%select{an attribute specifier sequence|%0}1 in this position "
- "is a C++23 extension">, InGroup<CXX23>;+ "is a C++23 extension">, InGroup<CXX23AttrsOnLambda>;
def ext_lambda_missing_parens : ExtWarn< def ext_lambda_missing_parens : ExtWarn<
"lambda without a parameter clause is a C++23 extension">, "lambda without a parameter clause is a C++23 extension">,
InGroup<CXX23>; InGroup<CXX23>;
clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10064,6 +10064,8 @@ def warn_missing_case : Warning<"%plural{"
"3:enumeration values %1, %2, and %3 not handled in switch|" "3:enumeration values %1, %2, and %3 not handled in switch|"
":%0 enumeration values not handled in switch: %1, %2, %3...}0">, ":%0 enumeration values not handled in switch: %1, %2, %3...}0">,
InGroup<Switch>; InGroup<Switch>;
+def warn_switch_default : Warning<"'switch' missing 'default' label">,
+ InGroup<SwitchDefault>, DefaultIgnore;
def warn_unannotated_fallthrough : Warning< def warn_unannotated_fallthrough : Warning<
"unannotated fall-through between switch labels">, "unannotated fall-through between switch labels">,
clang/include/clang/Basic/Features.def
@@ -89,6 +89,8 @@ FEATURE(blocks, LangOpts.Blocks)
FEATURE(c_thread_safety_attributes, true) FEATURE(c_thread_safety_attributes, true)
FEATURE(cxx_exceptions, LangOpts.CXXExceptions) FEATURE(cxx_exceptions, LangOpts.CXXExceptions)
FEATURE(cxx_rtti, LangOpts.RTTI &&LangOpts.RTTIData) FEATURE(cxx_rtti, LangOpts.RTTI &&LangOpts.RTTIData)
+EXTENSION(define_target_os_macros,
+ PP.getPreprocessorOpts().DefineTargetOSMacros)
FEATURE(enumerator_attributes, true) FEATURE(enumerator_attributes, true)
FEATURE(nullability, true) FEATURE(nullability, true)
FEATURE(nullability_on_arrays, true) FEATURE(nullability_on_arrays, true)
clang/include/clang/Basic/OpenACCKinds.h
@@ -53,7 +53,7 @@ enum class OpenACCDirectiveKind {
Shutdown, Shutdown,
Set, Set,
Update, Update,
- // FIXME: wait construct.+ Wait,
// Procedure Calls in Compute Regions. // Procedure Calls in Compute Regions.
Routine, Routine,
clang/include/clang/Basic/SyncScope.h
@@ -40,6 +40,11 @@ namespace clang {
/// Update getAsString. /// Update getAsString.
/// ///
enum class SyncScope { enum class SyncScope {
+ SystemScope,
+ DeviceScope,
+ WorkgroupScope,
+ WavefrontScope,
+ SingleScope,
HIPSingleThread, HIPSingleThread,
HIPWavefront, HIPWavefront,
HIPWorkgroup, HIPWorkgroup,
@@ -54,6 +59,16 @@ enum class SyncScope {
inline llvm::StringRef getAsString(SyncScope S) { inline llvm::StringRef getAsString(SyncScope S) {
switch (S) { switch (S) {
+ case SyncScope::SystemScope:
+ return "system_scope";
+ case SyncScope::DeviceScope:
+ return "device_scope";
+ case SyncScope::WorkgroupScope:
+ return "workgroup_scope";
+ case SyncScope::WavefrontScope:
+ return "wavefront_scope";
+ case SyncScope::SingleScope:
+ return "single_scope";
case SyncScope::HIPSingleThread: case SyncScope::HIPSingleThread:
return "hip_singlethread"; return "hip_singlethread";
case SyncScope::HIPWavefront: case SyncScope::HIPWavefront:
@@ -77,7 +92,7 @@ inline llvm::StringRef getAsString(SyncScope S) {
} }
/// Defines the kind of atomic scope models. /// Defines the kind of atomic scope models.
-enum class AtomicScopeModelKind { None, OpenCL, HIP };+enum class AtomicScopeModelKind { None, OpenCL, HIP, Generic };
/// Defines the interface for synch scope model. /// Defines the interface for synch scope model.
class AtomicScopeModel { class AtomicScopeModel {
@@ -205,6 +220,56 @@ public:
} }
}; };
+/// Defines the generic atomic scope model.
+class AtomicScopeGenericModel : public AtomicScopeModel {
+public:
+ /// The enum values match predefined built-in macros __ATOMIC_SCOPE_*.
+ enum ID {
+ System = 0,
+ Device = 1,
+ Workgroup = 2,
+ Wavefront = 3,
+ Single = 4,
+ Last = Single
+ };
+
+ AtomicScopeGenericModel() = default;
+
+ SyncScope map(unsigned S) const override {
+ switch (static_cast<ID>(S)) {
+ case Device:
+ return SyncScope::DeviceScope;
+ case System:
+ return SyncScope::SystemScope;
+ case Workgroup:
+ return SyncScope::WorkgroupScope;
+ case Wavefront:
+ return SyncScope::WavefrontScope;
+ case Single:
+ return SyncScope::SingleScope;
+ }
+ llvm_unreachable("Invalid language sync scope value");
+ }
+
+ bool isValid(unsigned S) const override {
+ return S >= static_cast<unsigned>(System) &&
+ S <= static_cast<unsigned>(Last);
+ }
+
+ ArrayRef<unsigned> getRuntimeValues() const override {
+ static_assert(Last == Single, "Does not include all sync scopes");
+ static const unsigned Scopes[] = {
+ static_cast<unsigned>(Device), static_cast<unsigned>(System),
+ static_cast<unsigned>(Workgroup), static_cast<unsigned>(Wavefront),
+ static_cast<unsigned>(Single)};
+ return llvm::ArrayRef(Scopes);
+ }
+
+ unsigned getFallBackValue() const override {
+ return static_cast<unsigned>(System);
+ }
+};
+
inline std::unique_ptr<AtomicScopeModel> inline std::unique_ptr<AtomicScopeModel>
AtomicScopeModel::create(AtomicScopeModelKind K) { AtomicScopeModel::create(AtomicScopeModelKind K) {
switch (K) { switch (K) {
@@ -214,6 +279,8 @@ AtomicScopeModel::create(AtomicScopeModelKind K) {
return std::make_unique<AtomicScopeOpenCLModel>(); return std::make_unique<AtomicScopeOpenCLModel>();
case AtomicScopeModelKind::HIP: case AtomicScopeModelKind::HIP:
return std::make_unique<AtomicScopeHIPModel>(); return std::make_unique<AtomicScopeHIPModel>();
+ case AtomicScopeModelKind::Generic:
+ return std::make_unique<AtomicScopeGenericModel>();
} }
llvm_unreachable("Invalid atomic scope model kind"); llvm_unreachable("Invalid atomic scope model kind");
} }
clang/include/clang/Basic/TargetOSMacros.def
@@ -0,0 +1,55 @@
+//===--- TargetOSMacros.def - Target OS macros ------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file specifies the predefined TARGET_OS_* conditional macros.
+// A target macro `Name` should be defined if `Predicate` evaluates to true.
+// The macro expects `const llvm::Triple &Triple` and the class `llvm::Triple`
+// to be available for the predicate.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TARGET_OS
+#define TARGET_OS(Name, Predicate)
+#endif
+
+// Windows targets.
+TARGET_OS(TARGET_OS_WIN32, Triple.isOSWindows())
+TARGET_OS(TARGET_OS_WINDOWS, Triple.isOSWindows())
+
+// Linux target.
+TARGET_OS(TARGET_OS_LINUX, Triple.isOSLinux())
+
+// Unix target.
+TARGET_OS(TARGET_OS_UNIX, Triple.isOSNetBSD() ||
+ Triple.isOSFreeBSD() ||
+ Triple.isOSOpenBSD() ||
+ Triple.isOSSolaris())
+
+// Apple (Mac) targets.
+TARGET_OS(TARGET_OS_MAC, Triple.isOSDarwin())
+TARGET_OS(TARGET_OS_OSX, Triple.isMacOSX())
+TARGET_OS(TARGET_OS_IPHONE, Triple.isiOS() || Triple.isTvOS() ||
+ Triple.isWatchOS())
+// Triple::isiOS() also includes tvOS
+TARGET_OS(TARGET_OS_IOS, Triple.getOS() == llvm::Triple::IOS)
+TARGET_OS(TARGET_OS_TV, Triple.isTvOS())
+TARGET_OS(TARGET_OS_WATCH, Triple.isWatchOS())
+TARGET_OS(TARGET_OS_DRIVERKIT, Triple.isDriverKit())
+TARGET_OS(TARGET_OS_MACCATALYST, Triple.isMacCatalystEnvironment())
+TARGET_OS(TARGET_OS_SIMULATOR, Triple.isSimulatorEnvironment())
+
+// Deprecated Apple target conditionals.
+TARGET_OS(TARGET_OS_EMBEDDED, (Triple.isiOS() || Triple.isTvOS() \
+ || Triple.isWatchOS()) \
+ && !Triple.isMacCatalystEnvironment() \
+ && !Triple.isSimulatorEnvironment())
+TARGET_OS(TARGET_OS_NANO, Triple.isWatchOS())
+TARGET_OS(TARGET_IPHONE_SIMULATOR, Triple.isSimulatorEnvironment())
+TARGET_OS(TARGET_OS_UIKITFORMAC, Triple.isMacCatalystEnvironment())
+
+#undef TARGET_OS
clang/include/clang/Basic/arm_sve.td
@@ -1296,6 +1296,11 @@ def SVCREATE_3_BF16 : SInst<"svcreate3[_{d}]", "3ddd", "b", MergeNone, "", [IsT
def SVCREATE_4_BF16 : SInst<"svcreate4[_{d}]", "4dddd", "b", MergeNone, "", [IsTupleCreate]>; def SVCREATE_4_BF16 : SInst<"svcreate4[_{d}]", "4dddd", "b", MergeNone, "", [IsTupleCreate]>;
} }
+let TargetGuard = "sve2p1" in {
+ def SVCREATE_2_B : SInst<"svcreate2[_{d}]", "2dd", "Pc", MergeNone, "", [IsTupleCreate]>;
+ def SVCREATE_4_B : SInst<"svcreate4[_{d}]", "4dddd", "Pc", MergeNone, "", [IsTupleCreate]>;
+}
+
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Vector insertion and extraction // Vector insertion and extraction
def SVGET_2 : SInst<"svget2[_{d}]", "d2i", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleGet], [ImmCheck<1, ImmCheck0_1>]>; def SVGET_2 : SInst<"svget2[_{d}]", "d2i", "csilUcUsUiUlhfd", MergeNone, "", [IsTupleGet], [ImmCheck<1, ImmCheck0_1>]>;
@@ -1316,6 +1321,13 @@ def SVSET_3_BF16 : SInst<"svset3[_{d}]", "33id", "b", MergeNone, "", [IsTupleSet
def SVSET_4_BF16 : SInst<"svset4[_{d}]", "44id", "b", MergeNone, "", [IsTupleSet], [ImmCheck<1, ImmCheck0_3>]>; def SVSET_4_BF16 : SInst<"svset4[_{d}]", "44id", "b", MergeNone, "", [IsTupleSet], [ImmCheck<1, ImmCheck0_3>]>;
} }
+let TargetGuard = "sve2p1" in {
+ def SVGET_2_B : SInst<"svget2[_{d}]", "d2i", "Pc", MergeNone, "", [IsTupleGet], [ImmCheck<1, ImmCheck0_1>]>;
+ def SVGET_4_B : SInst<"svget4[_{d}]", "d4i", "Pc", MergeNone, "", [IsTupleGet], [ImmCheck<1, ImmCheck0_3>]>;
+
+ def SVSET_2_B : SInst<"svset2[_{d}]", "22id", "Pc", MergeNone, "", [IsTupleSet], [ImmCheck<1, ImmCheck0_1>]>;
+ def SVSET_4_B : SInst<"svset4[_{d}]", "44id", "Pc", MergeNone, "", [IsTupleSet], [ImmCheck<1, ImmCheck0_3>]>;
+}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// SVE2 WhileGE/GT // SVE2 WhileGE/GT
let TargetGuard = "sve2" in { let TargetGuard = "sve2" in {
@@ -2134,6 +2146,24 @@ let TargetGuard = "sme2" in {
def SVURSHL_X2 : SInst<"svrshl[_{d}_x2]", "222", "UcUsUiUl", MergeNone, "aarch64_sve_urshl_x2", [IsStreaming], []>; def SVURSHL_X2 : SInst<"svrshl[_{d}_x2]", "222", "UcUsUiUl", MergeNone, "aarch64_sve_urshl_x2", [IsStreaming], []>;
def SVSRSHL_X4 : SInst<"svrshl[_{d}_x4]", "444", "csil", MergeNone, "aarch64_sve_srshl_x4", [IsStreaming], []>; def SVSRSHL_X4 : SInst<"svrshl[_{d}_x4]", "444", "csil", MergeNone, "aarch64_sve_srshl_x4", [IsStreaming], []>;
def SVURSHL_X4 : SInst<"svrshl[_{d}_x4]", "444", "UcUsUiUl", MergeNone, "aarch64_sve_urshl_x4", [IsStreaming], []>; def SVURSHL_X4 : SInst<"svrshl[_{d}_x4]", "444", "UcUsUiUl", MergeNone, "aarch64_sve_urshl_x4", [IsStreaming], []>;
+
+ def SVQRSHRN_X4 : SInst<"svqrshrn[_n]_{0}[_{d}_x4]", "q4i", "il", MergeNone, "aarch64_sve_sqrshrn_x4", [IsStreaming], [ImmCheck<1, ImmCheckShiftRight, 0>]>;
+ def SVUQRSHRN_X4 : SInst<"svqrshrn[_n]_{0}[_{d}_x4]", "b4i", "UiUl", MergeNone, "aarch64_sve_uqrshrn_x4", [IsStreaming], [ImmCheck<1, ImmCheckShiftRight, 0>]>;
+
+ // SQRSHR / UQRSHR
+ def SVQRSHR_X2 : SInst<"svqrshr[_n]_{0}[_{d}_x2]", "h2i", "i", MergeNone, "aarch64_sve_sqrshr_x2", [IsStreaming], [ImmCheck<1, ImmCheck1_16>]>;
+ def SVUQRSHR_X2 : SInst<"svqrshr[_n]_{0}[_{d}_x2]", "e2i", "Ui", MergeNone, "aarch64_sve_uqrshr_x2", [IsStreaming], [ImmCheck<1, ImmCheck1_16>]>;
+ def SVQRSHR_X4 : SInst<"svqrshr[_n]_{0}[_{d}_x4]", "q4i", "il", MergeNone, "aarch64_sve_sqrshr_x4", [IsStreaming], [ImmCheck<1, ImmCheckShiftRight, 0>]>;
+ def SVUQRSHR_X4 : SInst<"svqrshr[_n]_{0}[_{d}_x4]", "b4i", "UiUl", MergeNone, "aarch64_sve_uqrshr_x4", [IsStreaming], [ImmCheck<1, ImmCheckShiftRight, 0>]>;
+
+ // SQRSHRU
+ def SVSQRSHRU_X2 : SInst<"svqrshru[_n]_{0}[_{d}_x2]", "e2i", "i", MergeNone, "aarch64_sve_sqrshru_x2", [IsStreaming], [ImmCheck<1, ImmCheck1_16>]>;
+ def SVSQRSHRU_X4 : SInst<"svqrshru[_n]_{0}[_{d}_x4]", "b4i", "il", MergeNone, "aarch64_sve_sqrshru_x4", [IsStreaming], [ImmCheck<1, ImmCheckShiftRight, 0>]>;
+
+ def SVSQRSHRUN_X4 : SInst<"svqrshrun[_n]_{0}[_{d}_x4]", "b4i", "il", MergeNone, "aarch64_sve_sqrshrun_x4", [IsStreaming], [ImmCheck<1, ImmCheckShiftRight, 0>]>;
+
+ def REINTERPRET_SVBOOL_TO_SVCOUNT : Inst<"svreinterpret[_c]", "}P", "Pc", MergeNone, "", [IsStreamingCompatible], []>;
+ def REINTERPRET_SVCOUNT_TO_SVBOOL : Inst<"svreinterpret[_b]", "P}", "Pc", MergeNone, "", [IsStreamingCompatible], []>;
} }
let TargetGuard = "sve2p1" in { let TargetGuard = "sve2p1" in {
clang/include/clang/Driver/Multilib.h
@@ -130,7 +130,7 @@ public:
/// Select compatible variants, \returns false if none are compatible /// Select compatible variants, \returns false if none are compatible
bool select(const Multilib::flags_list &Flags, bool select(const Multilib::flags_list &Flags,
- llvm::SmallVector<Multilib> &) const;+ llvm::SmallVectorImpl<Multilib> &) const;
unsigned size() const { return Multilibs.size(); } unsigned size() const { return Multilibs.size(); }
clang/include/clang/Driver/Options.td
@@ -1818,6 +1818,9 @@ def fcomment_block_commands : CommaJoined<["-"], "fcomment-block-commands=">, Gr
Visibility<[ClangOption, CC1Option]>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Treat each comma separated argument in <arg> as a documentation comment block command">, HelpText<"Treat each comma separated argument in <arg> as a documentation comment block command">,
MetaVarName<"<arg>">, MarshallingInfoStringVector<LangOpts<"CommentOpts.BlockCommandNames">>; MetaVarName<"<arg>">, MarshallingInfoStringVector<LangOpts<"CommentOpts.BlockCommandNames">>;
+defm define_target_os_macros : OptInCC1FFlag<"define-target-os-macros",
+ "Enable", "Disable", " predefined target OS macros",
+ [ClangOption, CC1Option]>;
def fparse_all_comments : Flag<["-"], "fparse-all-comments">, Group<f_clang_Group>, def fparse_all_comments : Flag<["-"], "fparse-all-comments">, Group<f_clang_Group>,
Visibility<[ClangOption, CC1Option]>, Visibility<[ClangOption, CC1Option]>,
MarshallingInfoFlag<LangOpts<"CommentOpts.ParseAllComments">>; MarshallingInfoFlag<LangOpts<"CommentOpts.ParseAllComments">>;
clang/include/clang/Frontend/FrontendActions.h
@@ -151,6 +151,9 @@ class GenerateModuleInterfaceAction : public GenerateModuleAction {
private: private:
bool BeginSourceFileAction(CompilerInstance &CI) override; bool BeginSourceFileAction(CompilerInstance &CI) override;
+ std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
+
std::unique_ptr<raw_pwrite_stream> std::unique_ptr<raw_pwrite_stream>
CreateOutputFile(CompilerInstance &CI, StringRef InFile) override; CreateOutputFile(CompilerInstance &CI, StringRef InFile) override;
}; };
clang/include/clang/Lex/HeaderSearch.h
@@ -247,16 +247,13 @@ class HeaderSearch {
/// \#include search path information. Requests for \#include "x" search the /// \#include search path information. Requests for \#include "x" search the
/// directory of the \#including file first, then each directory in SearchDirs /// directory of the \#including file first, then each directory in SearchDirs
/// consecutively. Requests for <x> search the current dir first, then each /// consecutively. Requests for <x> search the current dir first, then each
- /// directory in SearchDirs, starting at AngledDirIdx, consecutively. If+ /// directory in SearchDirs, starting at AngledDirIdx, consecutively.
- /// NoCurDirSearch is true, then the check for the file in the current
- /// directory is suppressed.
std::vector<DirectoryLookup> SearchDirs; std::vector<DirectoryLookup> SearchDirs;
/// Whether the DirectoryLookup at the corresponding index in SearchDirs has /// Whether the DirectoryLookup at the corresponding index in SearchDirs has
/// been successfully used to lookup a file. /// been successfully used to lookup a file.
std::vector<bool> SearchDirsUsage; std::vector<bool> SearchDirsUsage;
unsigned AngledDirIdx = 0; unsigned AngledDirIdx = 0;
unsigned SystemDirIdx = 0; unsigned SystemDirIdx = 0;
- bool NoCurDirSearch = false;
/// Maps HeaderMap keys to SearchDir indices. When HeaderMaps are used /// Maps HeaderMap keys to SearchDir indices. When HeaderMaps are used
/// heavily, SearchDirs can start with thousands of HeaderMaps, so this Index /// heavily, SearchDirs can start with thousands of HeaderMaps, so this Index
@@ -373,7 +370,7 @@ public:
/// Interface for setting the file search paths. /// Interface for setting the file search paths.
void SetSearchPaths(std::vector<DirectoryLookup> dirs, unsigned angledDirIdx, void SetSearchPaths(std::vector<DirectoryLookup> dirs, unsigned angledDirIdx,
- unsigned systemDirIdx, bool noCurDirSearch,+ unsigned systemDirIdx,
llvm::DenseMap<unsigned, unsigned> searchDirToHSEntry); llvm::DenseMap<unsigned, unsigned> searchDirToHSEntry);
/// Add an additional search path. /// Add an additional search path.
clang/include/clang/Lex/PreprocessorOptions.h
@@ -76,6 +76,9 @@ public:
/// predefines. /// predefines.
bool UsePredefines = true; bool UsePredefines = true;
+ /// Indicates whether to predefine target OS macros.
+ bool DefineTargetOSMacros = false;
+
/// Whether we should maintain a detailed record of all macro /// Whether we should maintain a detailed record of all macro
/// definitions and expansions. /// definitions and expansions.
bool DetailedRecord = false; bool DetailedRecord = false;
clang/include/clang/Parse/Parser.h
@@ -3544,6 +3544,7 @@ private:
void ParseOpenACCCacheVarList(); void ParseOpenACCCacheVarList();
/// Parses a single variable in a variable list for the 'cache' construct. /// Parses a single variable in a variable list for the 'cache' construct.
bool ParseOpenACCCacheVar(); bool ParseOpenACCCacheVar();
+ bool ParseOpenACCWaitArgument();
private: private:
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
clang/include/clang/Sema/HLSLExternalSemaSource.h
@@ -30,9 +30,9 @@ class HLSLExternalSemaSource : public ExternalSemaSource {
void defineHLSLVectorAlias(); void defineHLSLVectorAlias();
void defineTrivialHLSLTypes(); void defineTrivialHLSLTypes();
- void forwardDeclareHLSLTypes();+ void defineHLSLTypesWithForwardDeclarations();
- void completeBufferType(CXXRecordDecl *Record);+ void onCompletion(CXXRecordDecl *Record, CompletionFunction Fn);
public: public:
~HLSLExternalSemaSource() override; ~HLSLExternalSemaSource() override;
clang/lib/AST/Expr.cpp
@@ -4887,6 +4887,7 @@ unsigned AtomicExpr::getNumSubExprs(AtomicOp Op) {
case AO__atomic_load_n: case AO__atomic_load_n:
return 2; return 2;
+ case AO__scoped_atomic_load_n:
case AO__opencl_atomic_load: case AO__opencl_atomic_load:
case AO__hip_atomic_load: case AO__hip_atomic_load:
case AO__c11_atomic_store: case AO__c11_atomic_store:
@@ -4921,6 +4922,26 @@ unsigned AtomicExpr::getNumSubExprs(AtomicOp Op) {
case AO__atomic_fetch_max: case AO__atomic_fetch_max:
return 3; return 3;
+ case AO__scoped_atomic_load:
+ case AO__scoped_atomic_store:
+ case AO__scoped_atomic_store_n:
+ case AO__scoped_atomic_fetch_add:
+ case AO__scoped_atomic_fetch_sub:
+ case AO__scoped_atomic_fetch_and:
+ case AO__scoped_atomic_fetch_or:
+ case AO__scoped_atomic_fetch_xor:
+ case AO__scoped_atomic_fetch_nand:
+ case AO__scoped_atomic_add_fetch:
+ case AO__scoped_atomic_sub_fetch:
+ case AO__scoped_atomic_and_fetch:
+ case AO__scoped_atomic_or_fetch:
+ case AO__scoped_atomic_xor_fetch:
+ case AO__scoped_atomic_nand_fetch:
+ case AO__scoped_atomic_min_fetch:
+ case AO__scoped_atomic_max_fetch:
+ case AO__scoped_atomic_fetch_min:
+ case AO__scoped_atomic_fetch_max:
+ case AO__scoped_atomic_exchange_n:
case AO__hip_atomic_exchange: case AO__hip_atomic_exchange:
case AO__hip_atomic_fetch_add: case AO__hip_atomic_fetch_add:
case AO__hip_atomic_fetch_sub: case AO__hip_atomic_fetch_sub:
@@ -4942,6 +4963,7 @@ unsigned AtomicExpr::getNumSubExprs(AtomicOp Op) {
case AO__atomic_exchange: case AO__atomic_exchange:
return 4; return 4;
+ case AO__scoped_atomic_exchange:
case AO__c11_atomic_compare_exchange_strong: case AO__c11_atomic_compare_exchange_strong:
case AO__c11_atomic_compare_exchange_weak: case AO__c11_atomic_compare_exchange_weak:
return 5; return 5;
@@ -4952,6 +4974,10 @@ unsigned AtomicExpr::getNumSubExprs(AtomicOp Op) {
case AO__atomic_compare_exchange: case AO__atomic_compare_exchange:
case AO__atomic_compare_exchange_n: case AO__atomic_compare_exchange_n:
return 6; return 6;
+
+ case AO__scoped_atomic_compare_exchange:
+ case AO__scoped_atomic_compare_exchange_n:
+ return 7;
} }
llvm_unreachable("unknown atomic op"); llvm_unreachable("unknown atomic op");
} }
clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -15,7 +15,6 @@
#include "Function.h" #include "Function.h"
#include "PrimType.h" #include "PrimType.h"
#include "Program.h" #include "Program.h"
-#include "State.h"
using namespace clang; using namespace clang;
using namespace clang::interp; using namespace clang::interp;
clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -34,6 +34,19 @@ PrimType getIntPrimType(const InterpState &S) {
llvm_unreachable("Int isn't 16 or 32 bit?"); llvm_unreachable("Int isn't 16 or 32 bit?");
} }
+PrimType getLongPrimType(const InterpState &S) {
+ const TargetInfo &TI = S.getCtx().getTargetInfo();
+ unsigned LongWidth = TI.getLongWidth();
+
+ if (LongWidth == 64)
+ return PT_Sint64;
+ else if (LongWidth == 32)
+ return PT_Sint32;
+ else if (LongWidth == 16)
+ return PT_Sint16;
+ llvm_unreachable("long isn't 16, 32 or 64 bit?");
+}
+
/// Peek an integer value from the stack into an APSInt. /// Peek an integer value from the stack into an APSInt.
static APSInt peekToAPSInt(InterpStack &Stk, PrimType T, size_t Offset = 0) { static APSInt peekToAPSInt(InterpStack &Stk, PrimType T, size_t Offset = 0) {
if (Offset == 0) if (Offset == 0)
@@ -110,6 +123,19 @@ static void pushAPSInt(InterpState &S, const APSInt &Val) {
} }
} }
+/// Pushes \p Val to the stack, as a target-dependent 'long'.
+static void pushLong(InterpState &S, int64_t Val) {
+ PrimType LongType = getLongPrimType(S);
+ if (LongType == PT_Sint64)
+ S.Stk.push<Integral<64, true>>(Integral<64, true>::from(Val));
+ else if (LongType == PT_Sint32)
+ S.Stk.push<Integral<32, true>>(Integral<32, true>::from(Val));
+ else if (LongType == PT_Sint16)
+ S.Stk.push<Integral<16, true>>(Integral<16, true>::from(Val));
+ else
+ llvm_unreachable("Long isn't 16, 32 or 64 bit?");
+}
+
static void pushSizeT(InterpState &S, uint64_t Val) { static void pushSizeT(InterpState &S, uint64_t Val) {
const TargetInfo &TI = S.getCtx().getTargetInfo(); const TargetInfo &TI = S.getCtx().getTargetInfo();
unsigned SizeTWidth = TI.getTypeWidth(TI.getSizeType()); unsigned SizeTWidth = TI.getTypeWidth(TI.getSizeType());
@@ -533,6 +559,26 @@ static bool interp__builtin_classify_type(InterpState &S, CodePtr OpPC,
return true; return true;
} }
+// __builtin_expect(long, long)
+// __builtin_expect_with_probability(long, long, double)
+static bool interp__builtin_expect(InterpState &S, CodePtr OpPC,
+ const InterpFrame *Frame,
+ const Function *Func, const CallExpr *Call) {
+ // The return value is simply the value of the first parameter.
+ // We ignore the probability.
+ unsigned NumArgs = Call->getNumArgs();
+ assert(NumArgs == 2 || NumArgs == 3);
+
+ PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
+ unsigned Offset = align(primSize(getLongPrimType(S))) * 2;
+ if (NumArgs == 3)
+ Offset += align(primSize(PT_Float));
+
+ APSInt Val = peekToAPSInt(S.Stk, ArgT, Offset);
+ pushLong(S, Val.getSExtValue());
+ return true;
+}
+
bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
const CallExpr *Call) { const CallExpr *Call) {
InterpFrame *Frame = S.Current; InterpFrame *Frame = S.Current;
@@ -702,6 +748,12 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
return false; return false;
break; break;
+ case Builtin::BI__builtin_expect:
+ case Builtin::BI__builtin_expect_with_probability:
+ if (!interp__builtin_expect(S, OpPC, Frame, F, Call))
+ return false;
+ break;
+
default: default:
return false; return false;
} }
clang/lib/AST/StmtPrinter.cpp
@@ -1841,6 +1841,7 @@ void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) {
PrintExpr(Node->getPtr()); PrintExpr(Node->getPtr());
if (Node->getOp() != AtomicExpr::AO__c11_atomic_load && if (Node->getOp() != AtomicExpr::AO__c11_atomic_load &&
Node->getOp() != AtomicExpr::AO__atomic_load_n && Node->getOp() != AtomicExpr::AO__atomic_load_n &&
+ Node->getOp() != AtomicExpr::AO__scoped_atomic_load_n &&
Node->getOp() != AtomicExpr::AO__opencl_atomic_load && Node->getOp() != AtomicExpr::AO__opencl_atomic_load &&
Node->getOp() != AtomicExpr::AO__hip_atomic_load) { Node->getOp() != AtomicExpr::AO__hip_atomic_load) {
OS << ", "; OS << ", ";
clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp
@@ -351,9 +351,10 @@ private:
if (Invalid) if (Invalid)
return; return;
- static constexpr unsigned Missing = -1;
// TokenInfo stores the BB and set of elements that a token is part of. // TokenInfo stores the BB and set of elements that a token is part of.
struct TokenInfo { struct TokenInfo {
+ enum : unsigned { Missing = static_cast<unsigned>(-1) };
+
// The basic block this is part of. // The basic block this is part of.
// This is the BB of the stmt with the smallest containing range. // This is the BB of the stmt with the smallest containing range.
unsigned BB = Missing; unsigned BB = Missing;
clang/lib/Analysis/ThreadSafety.cpp
@@ -1010,6 +1010,8 @@ class ThreadSafetyAnalyzer {
ThreadSafetyHandler &Handler; ThreadSafetyHandler &Handler;
const FunctionDecl *CurrentFunction; const FunctionDecl *CurrentFunction;
LocalVariableMap LocalVarMap; LocalVariableMap LocalVarMap;
+ // Maps constructed objects to `this` placeholder prior to initialization.
+ llvm::SmallDenseMap<const Expr *, til::LiteralPtr *> ConstructedObjects;
FactManager FactMan; FactManager FactMan;
std::vector<CFGBlockInfo> BlockInfo; std::vector<CFGBlockInfo> BlockInfo;
@@ -1543,8 +1545,6 @@ class BuildLockset : public ConstStmtVisitor<BuildLockset> {
FactSet FSet; FactSet FSet;
// The fact set for the function on exit. // The fact set for the function on exit.
const FactSet &FunctionExitFSet; const FactSet &FunctionExitFSet;
- /// Maps constructed objects to `this` placeholder prior to initialization.
- llvm::SmallDenseMap<const Expr *, til::LiteralPtr *> ConstructedObjects;
LocalVariableMap::Context LVarCtx; LocalVariableMap::Context LVarCtx;
unsigned CtxIndex; unsigned CtxIndex;
@@ -1808,7 +1808,7 @@ void BuildLockset::handleCall(const Expr *Exp, const NamedDecl *D,
std::pair<til::LiteralPtr *, StringRef> Placeholder = std::pair<til::LiteralPtr *, StringRef> Placeholder =
Analyzer->SxBuilder.createThisPlaceholder(Exp); Analyzer->SxBuilder.createThisPlaceholder(Exp);
[[maybe_unused]] auto inserted = [[maybe_unused]] auto inserted =
- ConstructedObjects.insert({Exp, Placeholder.first});+ Analyzer->ConstructedObjects.insert({Exp, Placeholder.first});
assert(inserted.second && "Are we visiting the same expression again?"); assert(inserted.second && "Are we visiting the same expression again?");
if (isa<CXXConstructExpr>(Exp)) if (isa<CXXConstructExpr>(Exp))
Self = Placeholder.first; Self = Placeholder.first;
@@ -2128,10 +2128,10 @@ void BuildLockset::VisitDeclStmt(const DeclStmt *S) {
E = EWC->getSubExpr()->IgnoreParens(); E = EWC->getSubExpr()->IgnoreParens();
E = UnpackConstruction(E); E = UnpackConstruction(E);
- if (auto Object = ConstructedObjects.find(E);+ if (auto Object = Analyzer->ConstructedObjects.find(E);
- Object != ConstructedObjects.end()) {+ Object != Analyzer->ConstructedObjects.end()) {
Object->second->setClangDecl(VD); Object->second->setClangDecl(VD);
- ConstructedObjects.erase(Object);+ Analyzer->ConstructedObjects.erase(Object);
} }
} }
} }
@@ -2140,11 +2140,11 @@ void BuildLockset::VisitDeclStmt(const DeclStmt *S) {
void BuildLockset::VisitMaterializeTemporaryExpr( void BuildLockset::VisitMaterializeTemporaryExpr(
const MaterializeTemporaryExpr *Exp) { const MaterializeTemporaryExpr *Exp) {
if (const ValueDecl *ExtD = Exp->getExtendingDecl()) { if (const ValueDecl *ExtD = Exp->getExtendingDecl()) {
- if (auto Object =+ if (auto Object = Analyzer->ConstructedObjects.find(
- ConstructedObjects.find(UnpackConstruction(Exp->getSubExpr()));+ UnpackConstruction(Exp->getSubExpr()));
- Object != ConstructedObjects.end()) {+ Object != Analyzer->ConstructedObjects.end()) {
Object->second->setClangDecl(ExtD); Object->second->setClangDecl(ExtD);
- ConstructedObjects.erase(Object);+ Analyzer->ConstructedObjects.erase(Object);
} }
} }
} }
@@ -2487,15 +2487,15 @@ void ThreadSafetyAnalyzer::runAnalysis(AnalysisDeclContext &AC) {
// Clean up constructed object even if there are no attributes to // Clean up constructed object even if there are no attributes to
// keep the number of objects in limbo as small as possible. // keep the number of objects in limbo as small as possible.
- if (auto Object = LocksetBuilder.ConstructedObjects.find(+ if (auto Object = ConstructedObjects.find(
TD.getBindTemporaryExpr()->getSubExpr()); TD.getBindTemporaryExpr()->getSubExpr());
- Object != LocksetBuilder.ConstructedObjects.end()) {+ Object != ConstructedObjects.end()) {
const auto *DD = TD.getDestructorDecl(AC.getASTContext()); const auto *DD = TD.getDestructorDecl(AC.getASTContext());
if (DD->hasAttrs()) if (DD->hasAttrs())
// TODO: the location here isn't quite correct. // TODO: the location here isn't quite correct.
LocksetBuilder.handleCall(nullptr, DD, Object->second, LocksetBuilder.handleCall(nullptr, DD, Object->second,
TD.getBindTemporaryExpr()->getEndLoc()); TD.getBindTemporaryExpr()->getEndLoc());
- LocksetBuilder.ConstructedObjects.erase(Object);+ ConstructedObjects.erase(Object);
} }
break; break;
} }
clang/lib/CodeGen/CGAtomic.cpp
@@ -507,9 +507,11 @@ static llvm::Value *EmitPostAtomicMinMax(CGBuilderTy &Builder,
default: default:
llvm_unreachable("Unexpected min/max operation"); llvm_unreachable("Unexpected min/max operation");
case AtomicExpr::AO__atomic_max_fetch: case AtomicExpr::AO__atomic_max_fetch:
+ case AtomicExpr::AO__scoped_atomic_max_fetch:
Pred = IsSigned ? llvm::CmpInst::ICMP_SGT : llvm::CmpInst::ICMP_UGT; Pred = IsSigned ? llvm::CmpInst::ICMP_SGT : llvm::CmpInst::ICMP_UGT;
break; break;
case AtomicExpr::AO__atomic_min_fetch: case AtomicExpr::AO__atomic_min_fetch:
+ case AtomicExpr::AO__scoped_atomic_min_fetch:
Pred = IsSigned ? llvm::CmpInst::ICMP_SLT : llvm::CmpInst::ICMP_ULT; Pred = IsSigned ? llvm::CmpInst::ICMP_SLT : llvm::CmpInst::ICMP_ULT;
break; break;
} }
@@ -544,7 +546,9 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest,
FailureOrder, Size, Order, Scope); FailureOrder, Size, Order, Scope);
return; return;
case AtomicExpr::AO__atomic_compare_exchange: case AtomicExpr::AO__atomic_compare_exchange:
- case AtomicExpr::AO__atomic_compare_exchange_n: {+ case AtomicExpr::AO__atomic_compare_exchange_n:
+ case AtomicExpr::AO__scoped_atomic_compare_exchange:
+ case AtomicExpr::AO__scoped_atomic_compare_exchange_n: {
if (llvm::ConstantInt *IsWeakC = dyn_cast<llvm::ConstantInt>(IsWeak)) { if (llvm::ConstantInt *IsWeakC = dyn_cast<llvm::ConstantInt>(IsWeak)) {
emitAtomicCmpXchgFailureSet(CGF, E, IsWeakC->getZExtValue(), Dest, Ptr, emitAtomicCmpXchgFailureSet(CGF, E, IsWeakC->getZExtValue(), Dest, Ptr,
Val1, Val2, FailureOrder, Size, Order, Scope); Val1, Val2, FailureOrder, Size, Order, Scope);
@@ -577,7 +581,9 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest,
case AtomicExpr::AO__opencl_atomic_load: case AtomicExpr::AO__opencl_atomic_load:
case AtomicExpr::AO__hip_atomic_load: case AtomicExpr::AO__hip_atomic_load:
case AtomicExpr::AO__atomic_load_n: case AtomicExpr::AO__atomic_load_n:
- case AtomicExpr::AO__atomic_load: {+ case AtomicExpr::AO__atomic_load:
+ case AtomicExpr::AO__scoped_atomic_load_n:
+ case AtomicExpr::AO__scoped_atomic_load: {
llvm::LoadInst *Load = CGF.Builder.CreateLoad(Ptr); llvm::LoadInst *Load = CGF.Builder.CreateLoad(Ptr);
Load->setAtomic(Order, Scope); Load->setAtomic(Order, Scope);
Load->setVolatile(E->isVolatile()); Load->setVolatile(E->isVolatile());
@@ -589,7 +595,9 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest,
case AtomicExpr::AO__opencl_atomic_store: case AtomicExpr::AO__opencl_atomic_store:
case AtomicExpr::AO__hip_atomic_store: case AtomicExpr::AO__hip_atomic_store:
case AtomicExpr::AO__atomic_store: case AtomicExpr::AO__atomic_store:
- case AtomicExpr::AO__atomic_store_n: {+ case AtomicExpr::AO__atomic_store_n:
+ case AtomicExpr::AO__scoped_atomic_store:
+ case AtomicExpr::AO__scoped_atomic_store_n: {
llvm::Value *LoadVal1 = CGF.Builder.CreateLoad(Val1); llvm::Value *LoadVal1 = CGF.Builder.CreateLoad(Val1);
llvm::StoreInst *Store = CGF.Builder.CreateStore(LoadVal1, Ptr); llvm::StoreInst *Store = CGF.Builder.CreateStore(LoadVal1, Ptr);
Store->setAtomic(Order, Scope); Store->setAtomic(Order, Scope);
@@ -602,10 +610,13 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest,
case AtomicExpr::AO__opencl_atomic_exchange: case AtomicExpr::AO__opencl_atomic_exchange:
case AtomicExpr::AO__atomic_exchange_n: case AtomicExpr::AO__atomic_exchange_n:
case AtomicExpr::AO__atomic_exchange: case AtomicExpr::AO__atomic_exchange:
+ case AtomicExpr::AO__scoped_atomic_exchange_n:
+ case AtomicExpr::AO__scoped_atomic_exchange:
Op = llvm::AtomicRMWInst::Xchg; Op = llvm::AtomicRMWInst::Xchg;
break; break;
case AtomicExpr::AO__atomic_add_fetch: case AtomicExpr::AO__atomic_add_fetch:
+ case AtomicExpr::AO__scoped_atomic_add_fetch:
PostOp = E->getValueType()->isFloatingType() ? llvm::Instruction::FAdd PostOp = E->getValueType()->isFloatingType() ? llvm::Instruction::FAdd
: llvm::Instruction::Add; : llvm::Instruction::Add;
[[fallthrough]]; [[fallthrough]];
@@ -613,11 +624,13 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest,
case AtomicExpr::AO__hip_atomic_fetch_add: case AtomicExpr::AO__hip_atomic_fetch_add:
case AtomicExpr::AO__opencl_atomic_fetch_add: case AtomicExpr::AO__opencl_atomic_fetch_add:
case AtomicExpr::AO__atomic_fetch_add: case AtomicExpr::AO__atomic_fetch_add:
+ case AtomicExpr::AO__scoped_atomic_fetch_add:
Op = E->getValueType()->isFloatingType() ? llvm::AtomicRMWInst::FAdd Op = E->getValueType()->isFloatingType() ? llvm::AtomicRMWInst::FAdd
: llvm::AtomicRMWInst::Add; : llvm::AtomicRMWInst::Add;
break; break;
case AtomicExpr::AO__atomic_sub_fetch: case AtomicExpr::AO__atomic_sub_fetch:
+ case AtomicExpr::AO__scoped_atomic_sub_fetch:
PostOp = E->getValueType()->isFloatingType() ? llvm::Instruction::FSub PostOp = E->getValueType()->isFloatingType() ? llvm::Instruction::FSub
: llvm::Instruction::Sub; : llvm::Instruction::Sub;
[[fallthrough]]; [[fallthrough]];
@@ -625,17 +638,20 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest,
case AtomicExpr::AO__hip_atomic_fetch_sub: case AtomicExpr::AO__hip_atomic_fetch_sub:
case AtomicExpr::AO__opencl_atomic_fetch_sub: case AtomicExpr::AO__opencl_atomic_fetch_sub:
case AtomicExpr::AO__atomic_fetch_sub: case AtomicExpr::AO__atomic_fetch_sub:
+ case AtomicExpr::AO__scoped_atomic_fetch_sub:
Op = E->getValueType()->isFloatingType() ? llvm::AtomicRMWInst::FSub Op = E->getValueType()->isFloatingType() ? llvm::AtomicRMWInst::FSub
: llvm::AtomicRMWInst::Sub; : llvm::AtomicRMWInst::Sub;
break; break;
case AtomicExpr::AO__atomic_min_fetch: case AtomicExpr::AO__atomic_min_fetch:
+ case AtomicExpr::AO__scoped_atomic_min_fetch:
PostOpMinMax = true; PostOpMinMax = true;
[[fallthrough]]; [[fallthrough]];
case AtomicExpr::AO__c11_atomic_fetch_min: case AtomicExpr::AO__c11_atomic_fetch_min:
case AtomicExpr::AO__hip_atomic_fetch_min: case AtomicExpr::AO__hip_atomic_fetch_min:
case AtomicExpr::AO__opencl_atomic_fetch_min: case AtomicExpr::AO__opencl_atomic_fetch_min:
case AtomicExpr::AO__atomic_fetch_min: case AtomicExpr::AO__atomic_fetch_min:
+ case AtomicExpr::AO__scoped_atomic_fetch_min:
Op = E->getValueType()->isFloatingType() Op = E->getValueType()->isFloatingType()
? llvm::AtomicRMWInst::FMin ? llvm::AtomicRMWInst::FMin
: (E->getValueType()->isSignedIntegerType() : (E->getValueType()->isSignedIntegerType()
@@ -644,12 +660,14 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest,
break; break;
case AtomicExpr::AO__atomic_max_fetch: case AtomicExpr::AO__atomic_max_fetch:
+ case AtomicExpr::AO__scoped_atomic_max_fetch:
PostOpMinMax = true; PostOpMinMax = true;
[[fallthrough]]; [[fallthrough]];
case AtomicExpr::AO__c11_atomic_fetch_max: case AtomicExpr::AO__c11_atomic_fetch_max:
case AtomicExpr::AO__hip_atomic_fetch_max: case AtomicExpr::AO__hip_atomic_fetch_max:
case AtomicExpr::AO__opencl_atomic_fetch_max: case AtomicExpr::AO__opencl_atomic_fetch_max:
case AtomicExpr::AO__atomic_fetch_max: case AtomicExpr::AO__atomic_fetch_max:
+ case AtomicExpr::AO__scoped_atomic_fetch_max:
Op = E->getValueType()->isFloatingType() Op = E->getValueType()->isFloatingType()
? llvm::AtomicRMWInst::FMax ? llvm::AtomicRMWInst::FMax
: (E->getValueType()->isSignedIntegerType() : (E->getValueType()->isSignedIntegerType()
@@ -658,40 +676,48 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest,
break; break;
case AtomicExpr::AO__atomic_and_fetch: case AtomicExpr::AO__atomic_and_fetch:
+ case AtomicExpr::AO__scoped_atomic_and_fetch:
PostOp = llvm::Instruction::And; PostOp = llvm::Instruction::And;
[[fallthrough]]; [[fallthrough]];
case AtomicExpr::AO__c11_atomic_fetch_and: case AtomicExpr::AO__c11_atomic_fetch_and:
case AtomicExpr::AO__hip_atomic_fetch_and: case AtomicExpr::AO__hip_atomic_fetch_and:
case AtomicExpr::AO__opencl_atomic_fetch_and: case AtomicExpr::AO__opencl_atomic_fetch_and:
case AtomicExpr::AO__atomic_fetch_and: case AtomicExpr::AO__atomic_fetch_and:
+ case AtomicExpr::AO__scoped_atomic_fetch_and:
Op = llvm::AtomicRMWInst::And; Op = llvm::AtomicRMWInst::And;
break; break;
case AtomicExpr::AO__atomic_or_fetch: case AtomicExpr::AO__atomic_or_fetch:
+ case AtomicExpr::AO__scoped_atomic_or_fetch:
PostOp = llvm::Instruction::Or; PostOp = llvm::Instruction::Or;
[[fallthrough]]; [[fallthrough]];
case AtomicExpr::AO__c11_atomic_fetch_or: case AtomicExpr::AO__c11_atomic_fetch_or:
case AtomicExpr::AO__hip_atomic_fetch_or: case AtomicExpr::AO__hip_atomic_fetch_or:
case AtomicExpr::AO__opencl_atomic_fetch_or: case AtomicExpr::AO__opencl_atomic_fetch_or:
case AtomicExpr::AO__atomic_fetch_or: case AtomicExpr::AO__atomic_fetch_or:
+ case AtomicExpr::AO__scoped_atomic_fetch_or:
Op = llvm::AtomicRMWInst::Or; Op = llvm::AtomicRMWInst::Or;
break; break;
case AtomicExpr::AO__atomic_xor_fetch: case AtomicExpr::AO__atomic_xor_fetch:
+ case AtomicExpr::AO__scoped_atomic_xor_fetch:
PostOp = llvm::Instruction::Xor; PostOp = llvm::Instruction::Xor;
[[fallthrough]]; [[fallthrough]];
case AtomicExpr::AO__c11_atomic_fetch_xor: case AtomicExpr::AO__c11_atomic_fetch_xor:
case AtomicExpr::AO__hip_atomic_fetch_xor: case AtomicExpr::AO__hip_atomic_fetch_xor:
case AtomicExpr::AO__opencl_atomic_fetch_xor: case AtomicExpr::AO__opencl_atomic_fetch_xor:
case AtomicExpr::AO__atomic_fetch_xor: case AtomicExpr::AO__atomic_fetch_xor:
+ case AtomicExpr::AO__scoped_atomic_fetch_xor:
Op = llvm::AtomicRMWInst::Xor; Op = llvm::AtomicRMWInst::Xor;
break; break;
case AtomicExpr::AO__atomic_nand_fetch: case AtomicExpr::AO__atomic_nand_fetch:
+ case AtomicExpr::AO__scoped_atomic_nand_fetch:
PostOp = llvm::Instruction::And; // the NOT is special cased below PostOp = llvm::Instruction::And; // the NOT is special cased below
[[fallthrough]]; [[fallthrough]];
case AtomicExpr::AO__c11_atomic_fetch_nand: case AtomicExpr::AO__c11_atomic_fetch_nand:
case AtomicExpr::AO__atomic_fetch_nand: case AtomicExpr::AO__atomic_fetch_nand:
+ case AtomicExpr::AO__scoped_atomic_fetch_nand:
Op = llvm::AtomicRMWInst::Nand; Op = llvm::AtomicRMWInst::Nand;
break; break;
} }
@@ -711,7 +737,8 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest,
else if (PostOp) else if (PostOp)
Result = CGF.Builder.CreateBinOp((llvm::Instruction::BinaryOps)PostOp, RMWI, Result = CGF.Builder.CreateBinOp((llvm::Instruction::BinaryOps)PostOp, RMWI,
LoadVal1); LoadVal1);
- if (E->getOp() == AtomicExpr::AO__atomic_nand_fetch)+ if (E->getOp() == AtomicExpr::AO__atomic_nand_fetch ||
+ E->getOp() == AtomicExpr::AO__scoped_atomic_nand_fetch)
Result = CGF.Builder.CreateNot(Result); Result = CGF.Builder.CreateNot(Result);
CGF.Builder.CreateStore(Result, Dest); CGF.Builder.CreateStore(Result, Dest);
} }
@@ -861,20 +888,24 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
llvm_unreachable("Already handled above with EmitAtomicInit!"); llvm_unreachable("Already handled above with EmitAtomicInit!");
case AtomicExpr::AO__atomic_load_n: case AtomicExpr::AO__atomic_load_n:
+ case AtomicExpr::AO__scoped_atomic_load_n:
case AtomicExpr::AO__c11_atomic_load: case AtomicExpr::AO__c11_atomic_load:
case AtomicExpr::AO__opencl_atomic_load: case AtomicExpr::AO__opencl_atomic_load:
case AtomicExpr::AO__hip_atomic_load: case AtomicExpr::AO__hip_atomic_load:
break; break;
case AtomicExpr::AO__atomic_load: case AtomicExpr::AO__atomic_load:
+ case AtomicExpr::AO__scoped_atomic_load:
Dest = EmitPointerWithAlignment(E->getVal1()); Dest = EmitPointerWithAlignment(E->getVal1());
break; break;
case AtomicExpr::AO__atomic_store: case AtomicExpr::AO__atomic_store:
+ case AtomicExpr::AO__scoped_atomic_store:
Val1 = EmitPointerWithAlignment(E->getVal1()); Val1 = EmitPointerWithAlignment(E->getVal1());
break; break;
case AtomicExpr::AO__atomic_exchange: case AtomicExpr::AO__atomic_exchange:
+ case AtomicExpr::AO__scoped_atomic_exchange:
Val1 = EmitPointerWithAlignment(E->getVal1()); Val1 = EmitPointerWithAlignment(E->getVal1());
Dest = EmitPointerWithAlignment(E->getVal2()); Dest = EmitPointerWithAlignment(E->getVal2());
break; break;
@@ -887,14 +918,19 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
case AtomicExpr::AO__hip_atomic_compare_exchange_strong: case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
case AtomicExpr::AO__opencl_atomic_compare_exchange_weak: case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
case AtomicExpr::AO__opencl_atomic_compare_exchange_strong: case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
+ case AtomicExpr::AO__scoped_atomic_compare_exchange:
+ case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
Val1 = EmitPointerWithAlignment(E->getVal1()); Val1 = EmitPointerWithAlignment(E->getVal1());
- if (E->getOp() == AtomicExpr::AO__atomic_compare_exchange)+ if (E->getOp() == AtomicExpr::AO__atomic_compare_exchange ||
+ E->getOp() == AtomicExpr::AO__scoped_atomic_compare_exchange)
Val2 = EmitPointerWithAlignment(E->getVal2()); Val2 = EmitPointerWithAlignment(E->getVal2());
else else
Val2 = EmitValToTemp(*this, E->getVal2()); Val2 = EmitValToTemp(*this, E->getVal2());
OrderFail = EmitScalarExpr(E->getOrderFail()); OrderFail = EmitScalarExpr(E->getOrderFail());
if (E->getOp() == AtomicExpr::AO__atomic_compare_exchange_n || if (E->getOp() == AtomicExpr::AO__atomic_compare_exchange_n ||
- E->getOp() == AtomicExpr::AO__atomic_compare_exchange)+ E->getOp() == AtomicExpr::AO__atomic_compare_exchange ||
+ E->getOp() == AtomicExpr::AO__scoped_atomic_compare_exchange_n ||
+ E->getOp() == AtomicExpr::AO__scoped_atomic_compare_exchange)
IsWeak = EmitScalarExpr(E->getWeak()); IsWeak = EmitScalarExpr(E->getWeak());
break; break;
@@ -934,6 +970,14 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
case AtomicExpr::AO__opencl_atomic_fetch_min: case AtomicExpr::AO__opencl_atomic_fetch_min:
case AtomicExpr::AO__hip_atomic_fetch_max: case AtomicExpr::AO__hip_atomic_fetch_max:
case AtomicExpr::AO__hip_atomic_fetch_min: case AtomicExpr::AO__hip_atomic_fetch_min:
+ case AtomicExpr::AO__scoped_atomic_fetch_add:
+ case AtomicExpr::AO__scoped_atomic_fetch_max:
+ case AtomicExpr::AO__scoped_atomic_fetch_min:
+ case AtomicExpr::AO__scoped_atomic_fetch_sub:
+ case AtomicExpr::AO__scoped_atomic_add_fetch:
+ case AtomicExpr::AO__scoped_atomic_max_fetch:
+ case AtomicExpr::AO__scoped_atomic_min_fetch:
+ case AtomicExpr::AO__scoped_atomic_sub_fetch:
ShouldCastToIntPtrTy = !MemTy->isFloatingType(); ShouldCastToIntPtrTy = !MemTy->isFloatingType();
[[fallthrough]]; [[fallthrough]];
@@ -963,6 +1007,16 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
case AtomicExpr::AO__opencl_atomic_fetch_xor: case AtomicExpr::AO__opencl_atomic_fetch_xor:
case AtomicExpr::AO__opencl_atomic_store: case AtomicExpr::AO__opencl_atomic_store:
case AtomicExpr::AO__opencl_atomic_exchange: case AtomicExpr::AO__opencl_atomic_exchange:
+ case AtomicExpr::AO__scoped_atomic_fetch_and:
+ case AtomicExpr::AO__scoped_atomic_fetch_nand:
+ case AtomicExpr::AO__scoped_atomic_fetch_or:
+ case AtomicExpr::AO__scoped_atomic_fetch_xor:
+ case AtomicExpr::AO__scoped_atomic_and_fetch:
+ case AtomicExpr::AO__scoped_atomic_nand_fetch:
+ case AtomicExpr::AO__scoped_atomic_or_fetch:
+ case AtomicExpr::AO__scoped_atomic_xor_fetch:
+ case AtomicExpr::AO__scoped_atomic_store_n:
+ case AtomicExpr::AO__scoped_atomic_exchange_n:
Val1 = EmitValToTemp(*this, E->getVal1()); Val1 = EmitValToTemp(*this, E->getVal1());
break; break;
} }
@@ -1039,6 +1093,22 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
case AtomicExpr::AO__opencl_atomic_fetch_or: case AtomicExpr::AO__opencl_atomic_fetch_or:
case AtomicExpr::AO__opencl_atomic_fetch_sub: case AtomicExpr::AO__opencl_atomic_fetch_sub:
case AtomicExpr::AO__opencl_atomic_fetch_xor: case AtomicExpr::AO__opencl_atomic_fetch_xor:
+ case AtomicExpr::AO__scoped_atomic_fetch_add:
+ case AtomicExpr::AO__scoped_atomic_fetch_and:
+ case AtomicExpr::AO__scoped_atomic_fetch_max:
+ case AtomicExpr::AO__scoped_atomic_fetch_min:
+ case AtomicExpr::AO__scoped_atomic_fetch_nand:
+ case AtomicExpr::AO__scoped_atomic_fetch_or:
+ case AtomicExpr::AO__scoped_atomic_fetch_sub:
+ case AtomicExpr::AO__scoped_atomic_fetch_xor:
+ case AtomicExpr::AO__scoped_atomic_add_fetch:
+ case AtomicExpr::AO__scoped_atomic_and_fetch:
+ case AtomicExpr::AO__scoped_atomic_max_fetch:
+ case AtomicExpr::AO__scoped_atomic_min_fetch:
+ case AtomicExpr::AO__scoped_atomic_nand_fetch:
+ case AtomicExpr::AO__scoped_atomic_or_fetch:
+ case AtomicExpr::AO__scoped_atomic_sub_fetch:
+ case AtomicExpr::AO__scoped_atomic_xor_fetch:
// For these, only library calls for certain sizes exist. // For these, only library calls for certain sizes exist.
UseOptimizedLibcall = true; UseOptimizedLibcall = true;
break; break;
@@ -1047,6 +1117,10 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
case AtomicExpr::AO__atomic_store: case AtomicExpr::AO__atomic_store:
case AtomicExpr::AO__atomic_exchange: case AtomicExpr::AO__atomic_exchange:
case AtomicExpr::AO__atomic_compare_exchange: case AtomicExpr::AO__atomic_compare_exchange:
+ case AtomicExpr::AO__scoped_atomic_load:
+ case AtomicExpr::AO__scoped_atomic_store:
+ case AtomicExpr::AO__scoped_atomic_exchange:
+ case AtomicExpr::AO__scoped_atomic_compare_exchange:
// Use the generic version if we don't know that the operand will be // Use the generic version if we don't know that the operand will be
// suitably aligned for the optimized version. // suitably aligned for the optimized version.
if (Misaligned) if (Misaligned)
@@ -1071,6 +1145,10 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
case AtomicExpr::AO__opencl_atomic_exchange: case AtomicExpr::AO__opencl_atomic_exchange:
case AtomicExpr::AO__opencl_atomic_compare_exchange_weak: case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
case AtomicExpr::AO__opencl_atomic_compare_exchange_strong: case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
+ case AtomicExpr::AO__scoped_atomic_load_n:
+ case AtomicExpr::AO__scoped_atomic_store_n:
+ case AtomicExpr::AO__scoped_atomic_exchange_n:
+ case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
// Only use optimized library calls for sizes for which they exist. // Only use optimized library calls for sizes for which they exist.
// FIXME: Size == 16 optimized library functions exist too. // FIXME: Size == 16 optimized library functions exist too.
if (Size == 1 || Size == 2 || Size == 4 || Size == 8) if (Size == 1 || Size == 2 || Size == 4 || Size == 8)
@@ -1131,6 +1209,8 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
case AtomicExpr::AO__hip_atomic_compare_exchange_strong: case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
case AtomicExpr::AO__opencl_atomic_compare_exchange_weak: case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
case AtomicExpr::AO__opencl_atomic_compare_exchange_strong: case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
+ case AtomicExpr::AO__scoped_atomic_compare_exchange:
+ case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
LibCallName = "__atomic_compare_exchange"; LibCallName = "__atomic_compare_exchange";
RetTy = getContext().BoolTy; RetTy = getContext().BoolTy;
HaveRetTy = true; HaveRetTy = true;
@@ -1150,6 +1230,8 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
case AtomicExpr::AO__c11_atomic_exchange: case AtomicExpr::AO__c11_atomic_exchange:
case AtomicExpr::AO__hip_atomic_exchange: case AtomicExpr::AO__hip_atomic_exchange:
case AtomicExpr::AO__opencl_atomic_exchange: case AtomicExpr::AO__opencl_atomic_exchange:
+ case AtomicExpr::AO__scoped_atomic_exchange:
+ case AtomicExpr::AO__scoped_atomic_exchange_n:
LibCallName = "__atomic_exchange"; LibCallName = "__atomic_exchange";
AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(),
MemTy, E->getExprLoc(), TInfo.Width); MemTy, E->getExprLoc(), TInfo.Width);
@@ -1161,6 +1243,8 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
case AtomicExpr::AO__c11_atomic_store: case AtomicExpr::AO__c11_atomic_store:
case AtomicExpr::AO__hip_atomic_store: case AtomicExpr::AO__hip_atomic_store:
case AtomicExpr::AO__opencl_atomic_store: case AtomicExpr::AO__opencl_atomic_store:
+ case AtomicExpr::AO__scoped_atomic_store:
+ case AtomicExpr::AO__scoped_atomic_store_n:
LibCallName = "__atomic_store"; LibCallName = "__atomic_store";
RetTy = getContext().VoidTy; RetTy = getContext().VoidTy;
HaveRetTy = true; HaveRetTy = true;
@@ -1174,17 +1258,21 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
case AtomicExpr::AO__c11_atomic_load: case AtomicExpr::AO__c11_atomic_load:
case AtomicExpr::AO__hip_atomic_load: case AtomicExpr::AO__hip_atomic_load:
case AtomicExpr::AO__opencl_atomic_load: case AtomicExpr::AO__opencl_atomic_load:
+ case AtomicExpr::AO__scoped_atomic_load:
+ case AtomicExpr::AO__scoped_atomic_load_n:
LibCallName = "__atomic_load"; LibCallName = "__atomic_load";
break; break;
// T __atomic_add_fetch_N(T *mem, T val, int order) // T __atomic_add_fetch_N(T *mem, T val, int order)
// T __atomic_fetch_add_N(T *mem, T val, int order) // T __atomic_fetch_add_N(T *mem, T val, int order)
case AtomicExpr::AO__atomic_add_fetch: case AtomicExpr::AO__atomic_add_fetch:
+ case AtomicExpr::AO__scoped_atomic_add_fetch:
PostOp = llvm::Instruction::Add; PostOp = llvm::Instruction::Add;
[[fallthrough]]; [[fallthrough]];
case AtomicExpr::AO__atomic_fetch_add: case AtomicExpr::AO__atomic_fetch_add:
case AtomicExpr::AO__c11_atomic_fetch_add: case AtomicExpr::AO__c11_atomic_fetch_add:
case AtomicExpr::AO__hip_atomic_fetch_add: case AtomicExpr::AO__hip_atomic_fetch_add:
case AtomicExpr::AO__opencl_atomic_fetch_add: case AtomicExpr::AO__opencl_atomic_fetch_add:
+ case AtomicExpr::AO__scoped_atomic_fetch_add:
LibCallName = "__atomic_fetch_add"; LibCallName = "__atomic_fetch_add";
AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(),
LoweredMemTy, E->getExprLoc(), TInfo.Width); LoweredMemTy, E->getExprLoc(), TInfo.Width);
@@ -1192,12 +1280,14 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
// T __atomic_and_fetch_N(T *mem, T val, int order) // T __atomic_and_fetch_N(T *mem, T val, int order)
// T __atomic_fetch_and_N(T *mem, T val, int order) // T __atomic_fetch_and_N(T *mem, T val, int order)
case AtomicExpr::AO__atomic_and_fetch: case AtomicExpr::AO__atomic_and_fetch:
+ case AtomicExpr::AO__scoped_atomic_and_fetch:
PostOp = llvm::Instruction::And; PostOp = llvm::Instruction::And;
[[fallthrough]]; [[fallthrough]];
case AtomicExpr::AO__atomic_fetch_and: case AtomicExpr::AO__atomic_fetch_and:
case AtomicExpr::AO__c11_atomic_fetch_and: case AtomicExpr::AO__c11_atomic_fetch_and:
case AtomicExpr::AO__hip_atomic_fetch_and: case AtomicExpr::AO__hip_atomic_fetch_and:
case AtomicExpr::AO__opencl_atomic_fetch_and: case AtomicExpr::AO__opencl_atomic_fetch_and:
+ case AtomicExpr::AO__scoped_atomic_fetch_and:
LibCallName = "__atomic_fetch_and"; LibCallName = "__atomic_fetch_and";
AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(),
MemTy, E->getExprLoc(), TInfo.Width); MemTy, E->getExprLoc(), TInfo.Width);
@@ -1205,12 +1295,14 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
// T __atomic_or_fetch_N(T *mem, T val, int order) // T __atomic_or_fetch_N(T *mem, T val, int order)
// T __atomic_fetch_or_N(T *mem, T val, int order) // T __atomic_fetch_or_N(T *mem, T val, int order)
case AtomicExpr::AO__atomic_or_fetch: case AtomicExpr::AO__atomic_or_fetch:
+ case AtomicExpr::AO__scoped_atomic_or_fetch:
PostOp = llvm::Instruction::Or; PostOp = llvm::Instruction::Or;
[[fallthrough]]; [[fallthrough]];
case AtomicExpr::AO__atomic_fetch_or: case AtomicExpr::AO__atomic_fetch_or:
case AtomicExpr::AO__c11_atomic_fetch_or: case AtomicExpr::AO__c11_atomic_fetch_or:
case AtomicExpr::AO__hip_atomic_fetch_or: case AtomicExpr::AO__hip_atomic_fetch_or:
case AtomicExpr::AO__opencl_atomic_fetch_or: case AtomicExpr::AO__opencl_atomic_fetch_or:
+ case AtomicExpr::AO__scoped_atomic_fetch_or:
LibCallName = "__atomic_fetch_or"; LibCallName = "__atomic_fetch_or";
AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(),
MemTy, E->getExprLoc(), TInfo.Width); MemTy, E->getExprLoc(), TInfo.Width);
@@ -1218,12 +1310,14 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
// T __atomic_sub_fetch_N(T *mem, T val, int order) // T __atomic_sub_fetch_N(T *mem, T val, int order)
// T __atomic_fetch_sub_N(T *mem, T val, int order) // T __atomic_fetch_sub_N(T *mem, T val, int order)
case AtomicExpr::AO__atomic_sub_fetch: case AtomicExpr::AO__atomic_sub_fetch:
+ case AtomicExpr::AO__scoped_atomic_sub_fetch:
PostOp = llvm::Instruction::Sub; PostOp = llvm::Instruction::Sub;
[[fallthrough]]; [[fallthrough]];
case AtomicExpr::AO__atomic_fetch_sub: case AtomicExpr::AO__atomic_fetch_sub:
case AtomicExpr::AO__c11_atomic_fetch_sub: case AtomicExpr::AO__c11_atomic_fetch_sub:
case AtomicExpr::AO__hip_atomic_fetch_sub: case AtomicExpr::AO__hip_atomic_fetch_sub:
case AtomicExpr::AO__opencl_atomic_fetch_sub: case AtomicExpr::AO__opencl_atomic_fetch_sub:
+ case AtomicExpr::AO__scoped_atomic_fetch_sub:
LibCallName = "__atomic_fetch_sub"; LibCallName = "__atomic_fetch_sub";
AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(),
LoweredMemTy, E->getExprLoc(), TInfo.Width); LoweredMemTy, E->getExprLoc(), TInfo.Width);
@@ -1231,21 +1325,25 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
// T __atomic_xor_fetch_N(T *mem, T val, int order) // T __atomic_xor_fetch_N(T *mem, T val, int order)
// T __atomic_fetch_xor_N(T *mem, T val, int order) // T __atomic_fetch_xor_N(T *mem, T val, int order)
case AtomicExpr::AO__atomic_xor_fetch: case AtomicExpr::AO__atomic_xor_fetch:
+ case AtomicExpr::AO__scoped_atomic_xor_fetch:
PostOp = llvm::Instruction::Xor; PostOp = llvm::Instruction::Xor;
[[fallthrough]]; [[fallthrough]];
case AtomicExpr::AO__atomic_fetch_xor: case AtomicExpr::AO__atomic_fetch_xor:
case AtomicExpr::AO__c11_atomic_fetch_xor: case AtomicExpr::AO__c11_atomic_fetch_xor:
case AtomicExpr::AO__hip_atomic_fetch_xor: case AtomicExpr::AO__hip_atomic_fetch_xor:
case AtomicExpr::AO__opencl_atomic_fetch_xor: case AtomicExpr::AO__opencl_atomic_fetch_xor:
+ case AtomicExpr::AO__scoped_atomic_fetch_xor:
LibCallName = "__atomic_fetch_xor"; LibCallName = "__atomic_fetch_xor";
AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(),
MemTy, E->getExprLoc(), TInfo.Width); MemTy, E->getExprLoc(), TInfo.Width);
break; break;
case AtomicExpr::AO__atomic_min_fetch: case AtomicExpr::AO__atomic_min_fetch:
+ case AtomicExpr::AO__scoped_atomic_min_fetch:
PostOpMinMax = true; PostOpMinMax = true;
[[fallthrough]]; [[fallthrough]];
case AtomicExpr::AO__atomic_fetch_min: case AtomicExpr::AO__atomic_fetch_min:
case AtomicExpr::AO__c11_atomic_fetch_min: case AtomicExpr::AO__c11_atomic_fetch_min:
+ case AtomicExpr::AO__scoped_atomic_fetch_min:
case AtomicExpr::AO__hip_atomic_fetch_min: case AtomicExpr::AO__hip_atomic_fetch_min:
case AtomicExpr::AO__opencl_atomic_fetch_min: case AtomicExpr::AO__opencl_atomic_fetch_min:
LibCallName = E->getValueType()->isSignedIntegerType() LibCallName = E->getValueType()->isSignedIntegerType()
@@ -1255,12 +1353,14 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
LoweredMemTy, E->getExprLoc(), TInfo.Width); LoweredMemTy, E->getExprLoc(), TInfo.Width);
break; break;
case AtomicExpr::AO__atomic_max_fetch: case AtomicExpr::AO__atomic_max_fetch:
+ case AtomicExpr::AO__scoped_atomic_max_fetch:
PostOpMinMax = true; PostOpMinMax = true;
[[fallthrough]]; [[fallthrough]];
case AtomicExpr::AO__atomic_fetch_max: case AtomicExpr::AO__atomic_fetch_max:
case AtomicExpr::AO__c11_atomic_fetch_max: case AtomicExpr::AO__c11_atomic_fetch_max:
case AtomicExpr::AO__hip_atomic_fetch_max: case AtomicExpr::AO__hip_atomic_fetch_max:
case AtomicExpr::AO__opencl_atomic_fetch_max: case AtomicExpr::AO__opencl_atomic_fetch_max:
+ case AtomicExpr::AO__scoped_atomic_fetch_max:
LibCallName = E->getValueType()->isSignedIntegerType() LibCallName = E->getValueType()->isSignedIntegerType()
? "__atomic_fetch_max" ? "__atomic_fetch_max"
: "__atomic_fetch_umax"; : "__atomic_fetch_umax";
@@ -1270,10 +1370,12 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
// T __atomic_nand_fetch_N(T *mem, T val, int order) // T __atomic_nand_fetch_N(T *mem, T val, int order)
// T __atomic_fetch_nand_N(T *mem, T val, int order) // T __atomic_fetch_nand_N(T *mem, T val, int order)
case AtomicExpr::AO__atomic_nand_fetch: case AtomicExpr::AO__atomic_nand_fetch:
+ case AtomicExpr::AO__scoped_atomic_nand_fetch:
PostOp = llvm::Instruction::And; // the NOT is special cased below PostOp = llvm::Instruction::And; // the NOT is special cased below
[[fallthrough]]; [[fallthrough]];
case AtomicExpr::AO__atomic_fetch_nand: case AtomicExpr::AO__atomic_fetch_nand:
case AtomicExpr::AO__c11_atomic_fetch_nand: case AtomicExpr::AO__c11_atomic_fetch_nand:
+ case AtomicExpr::AO__scoped_atomic_fetch_nand:
LibCallName = "__atomic_fetch_nand"; LibCallName = "__atomic_fetch_nand";
AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(),
MemTy, E->getExprLoc(), TInfo.Width); MemTy, E->getExprLoc(), TInfo.Width);
@@ -1330,7 +1432,8 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
llvm::Value *LoadVal1 = Args[1].getRValue(*this).getScalarVal(); llvm::Value *LoadVal1 = Args[1].getRValue(*this).getScalarVal();
ResVal = Builder.CreateBinOp(PostOp, ResVal, LoadVal1); ResVal = Builder.CreateBinOp(PostOp, ResVal, LoadVal1);
} }
- if (E->getOp() == AtomicExpr::AO__atomic_nand_fetch)+ if (E->getOp() == AtomicExpr::AO__atomic_nand_fetch ||
+ E->getOp() == AtomicExpr::AO__scoped_atomic_nand_fetch)
ResVal = Builder.CreateNot(ResVal); ResVal = Builder.CreateNot(ResVal);
Builder.CreateStore(ResVal, Dest.withElementType(ResVal->getType())); Builder.CreateStore(ResVal, Dest.withElementType(ResVal->getType()));
@@ -1347,12 +1450,16 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
E->getOp() == AtomicExpr::AO__opencl_atomic_store || E->getOp() == AtomicExpr::AO__opencl_atomic_store ||
E->getOp() == AtomicExpr::AO__hip_atomic_store || E->getOp() == AtomicExpr::AO__hip_atomic_store ||
E->getOp() == AtomicExpr::AO__atomic_store || E->getOp() == AtomicExpr::AO__atomic_store ||
- E->getOp() == AtomicExpr::AO__atomic_store_n;+ E->getOp() == AtomicExpr::AO__atomic_store_n ||
+ E->getOp() == AtomicExpr::AO__scoped_atomic_store ||
+ E->getOp() == AtomicExpr::AO__scoped_atomic_store_n;
bool IsLoad = E->getOp() == AtomicExpr::AO__c11_atomic_load || bool IsLoad = E->getOp() == AtomicExpr::AO__c11_atomic_load ||
E->getOp() == AtomicExpr::AO__opencl_atomic_load || E->getOp() == AtomicExpr::AO__opencl_atomic_load ||
E->getOp() == AtomicExpr::AO__hip_atomic_load || E->getOp() == AtomicExpr::AO__hip_atomic_load ||
E->getOp() == AtomicExpr::AO__atomic_load || E->getOp() == AtomicExpr::AO__atomic_load ||
- E->getOp() == AtomicExpr::AO__atomic_load_n;+ E->getOp() == AtomicExpr::AO__atomic_load_n ||
+ E->getOp() == AtomicExpr::AO__scoped_atomic_load ||
+ E->getOp() == AtomicExpr::AO__scoped_atomic_load_n;
if (isa<llvm::ConstantInt>(Order)) { if (isa<llvm::ConstantInt>(Order)) {
auto ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); auto ord = cast<llvm::ConstantInt>(Order)->getZExtValue();
clang/lib/CodeGen/CGBuiltin.cpp
@@ -10211,6 +10211,22 @@ Value *CodeGenFunction::EmitAArch64SVEBuiltinExpr(unsigned BuiltinID,
switch (BuiltinID) { switch (BuiltinID) {
default: default:
return nullptr; return nullptr;
+
+ case SVE::BI__builtin_sve_svreinterpret_b: {
+ auto SVCountTy =
+ llvm::TargetExtType::get(getLLVMContext(), "aarch64.svcount");
+ Function *CastFromSVCountF =
+ CGM.getIntrinsic(Intrinsic::aarch64_sve_convert_to_svbool, SVCountTy);
+ return Builder.CreateCall(CastFromSVCountF, Ops[0]);
+ }
+ case SVE::BI__builtin_sve_svreinterpret_c: {
+ auto SVCountTy =
+ llvm::TargetExtType::get(getLLVMContext(), "aarch64.svcount");
+ Function *CastToSVCountF =
+ CGM.getIntrinsic(Intrinsic::aarch64_sve_convert_from_svbool, SVCountTy);
+ return Builder.CreateCall(CastToSVCountF, Ops[0]);
+ }
+
case SVE::BI__builtin_sve_svpsel_lane_b8: case SVE::BI__builtin_sve_svpsel_lane_b8:
case SVE::BI__builtin_sve_svpsel_lane_b16: case SVE::BI__builtin_sve_svpsel_lane_b16:
case SVE::BI__builtin_sve_svpsel_lane_b32: case SVE::BI__builtin_sve_svpsel_lane_b32:
clang/lib/CodeGen/CGCUDANV.cpp
@@ -1132,26 +1132,39 @@ void CGNVCUDARuntime::createOffloadingEntries() {
for (KernelInfo &I : EmittedKernels) for (KernelInfo &I : EmittedKernels)
llvm::offloading::emitOffloadingEntry( llvm::offloading::emitOffloadingEntry(
M, KernelHandles[I.Kernel->getName()], M, KernelHandles[I.Kernel->getName()],
- getDeviceSideName(cast<NamedDecl>(I.D)), 0,+ getDeviceSideName(cast<NamedDecl>(I.D)), /*Flags=*/0, /*Data=*/0,
- DeviceVarFlags::OffloadGlobalEntry, Section);+ llvm::offloading::OffloadGlobalEntry, Section);
for (VarInfo &I : DeviceVars) { for (VarInfo &I : DeviceVars) {
uint64_t VarSize = uint64_t VarSize =
CGM.getDataLayout().getTypeAllocSize(I.Var->getValueType()); CGM.getDataLayout().getTypeAllocSize(I.Var->getValueType());
+ int32_t Flags =
+ (I.Flags.isExtern()
+ ? static_cast<int32_t>(llvm::offloading::OffloadGlobalExtern)
+ : 0) |
+ (I.Flags.isConstant()
+ ? static_cast<int32_t>(llvm::offloading::OffloadGlobalConstant)
+ : 0) |
+ (I.Flags.isNormalized()
+ ? static_cast<int32_t>(llvm::offloading::OffloadGlobalNormalized)
+ : 0);
if (I.Flags.getKind() == DeviceVarFlags::Variable) { if (I.Flags.getKind() == DeviceVarFlags::Variable) {
llvm::offloading::emitOffloadingEntry( llvm::offloading::emitOffloadingEntry(
M, I.Var, getDeviceSideName(I.D), VarSize, M, I.Var, getDeviceSideName(I.D), VarSize,
- I.Flags.isManaged() ? DeviceVarFlags::OffloadGlobalManagedEntry+ (I.Flags.isManaged() ? llvm::offloading::OffloadGlobalManagedEntry
- : DeviceVarFlags::OffloadGlobalEntry,+ : llvm::offloading::OffloadGlobalEntry) |
- Section);+ Flags,
+ /*Data=*/0, Section);
} else if (I.Flags.getKind() == DeviceVarFlags::Surface) { } else if (I.Flags.getKind() == DeviceVarFlags::Surface) {
llvm::offloading::emitOffloadingEntry( llvm::offloading::emitOffloadingEntry(
M, I.Var, getDeviceSideName(I.D), VarSize, M, I.Var, getDeviceSideName(I.D), VarSize,
- DeviceVarFlags::OffloadGlobalSurfaceEntry, Section);+ llvm::offloading::OffloadGlobalSurfaceEntry | Flags,
+ I.Flags.getSurfTexType(), Section);
} else if (I.Flags.getKind() == DeviceVarFlags::Texture) { } else if (I.Flags.getKind() == DeviceVarFlags::Texture) {
llvm::offloading::emitOffloadingEntry( llvm::offloading::emitOffloadingEntry(
M, I.Var, getDeviceSideName(I.D), VarSize, M, I.Var, getDeviceSideName(I.D), VarSize,
- DeviceVarFlags::OffloadGlobalTextureEntry, Section);+ llvm::offloading::OffloadGlobalTextureEntry | Flags,
+ I.Flags.getSurfTexType(), Section);
} }
} }
} }
clang/lib/CodeGen/CGCUDARuntime.h
@@ -17,6 +17,7 @@
#include "clang/AST/GlobalDecl.h" #include "clang/AST/GlobalDecl.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
+#include "llvm/Frontend/Offloading/Utility.h"
#include "llvm/IR/GlobalValue.h" #include "llvm/IR/GlobalValue.h"
namespace llvm { namespace llvm {
@@ -52,19 +53,6 @@ public:
Texture, // Builtin texture Texture, // Builtin texture
}; };
- /// The kind flag for an offloading entry.
- enum OffloadEntryKindFlag : uint32_t {
- /// Mark the entry as a global entry. This indicates the presense of a
- /// kernel if the size field is zero and a variable otherwise.
- OffloadGlobalEntry = 0x0,
- /// Mark the entry as a managed global variable.
- OffloadGlobalManagedEntry = 0x1,
- /// Mark the entry as a surface variable.
- OffloadGlobalSurfaceEntry = 0x2,
- /// Mark the entry as a texture variable.
- OffloadGlobalTextureEntry = 0x3,
- };
-
private: private:
unsigned Kind : 2; unsigned Kind : 2;
unsigned Extern : 1; unsigned Extern : 1;
clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -7389,7 +7389,14 @@ private:
} else if (FieldIndex < PartialStruct.LowestElem.first) { } else if (FieldIndex < PartialStruct.LowestElem.first) {
PartialStruct.LowestElem = {FieldIndex, LowestElem}; PartialStruct.LowestElem = {FieldIndex, LowestElem};
} else if (FieldIndex > PartialStruct.HighestElem.first) { } else if (FieldIndex > PartialStruct.HighestElem.first) {
- PartialStruct.HighestElem = {FieldIndex, LowestElem};+ if (IsFinalArraySection) {
+ Address HB =
+ CGF.EmitOMPArraySectionExpr(OASE, /*IsLowerBound=*/false)
+ .getAddress(CGF);
+ PartialStruct.HighestElem = {FieldIndex, HB};
+ } else {
+ PartialStruct.HighestElem = {FieldIndex, LowestElem};
+ }
} }
} }
clang/lib/CodeGen/CodeGenModule.cpp
@@ -6439,7 +6439,7 @@ ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary(
VD, E->getManglingNumber(), Out); VD, E->getManglingNumber(), Out);
APValue *Value = nullptr; APValue *Value = nullptr;
- if (E->getStorageDuration() == SD_Static && VD && VD->evaluateValue()) {+ if (E->getStorageDuration() == SD_Static && VD->evaluateValue()) {
// If the initializer of the extending declaration is a constant // If the initializer of the extending declaration is a constant
// initializer, we should have a cached constant initializer for this // initializer, we should have a cached constant initializer for this
// temporary. Note that this might have a different value from the value // temporary. Note that this might have a different value from the value
@@ -6454,8 +6454,7 @@ ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary(
!EvalResult.hasSideEffects()) !EvalResult.hasSideEffects())
Value = &EvalResult.Val; Value = &EvalResult.Val;
- LangAS AddrSpace =+ LangAS AddrSpace = GetGlobalVarAddressSpace(VD);
- VD ? GetGlobalVarAddressSpace(VD) : MaterializedType.getAddressSpace();
std::optional<ConstantEmitter> emitter; std::optional<ConstantEmitter> emitter;
llvm::Constant *InitialValue = nullptr; llvm::Constant *InitialValue = nullptr;
clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -196,11 +196,14 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
// Enum types are distinct types. In C++ they have "underlying types", // Enum types are distinct types. In C++ they have "underlying types",
// however they aren't related for TBAA. // however they aren't related for TBAA.
if (const EnumType *ETy = dyn_cast<EnumType>(Ty)) { if (const EnumType *ETy = dyn_cast<EnumType>(Ty)) {
+ if (!Features.CPlusPlus)
+ return getTypeInfo(ETy->getDecl()->getIntegerType());
+
// In C++ mode, types have linkage, so we can rely on the ODR and // In C++ mode, types have linkage, so we can rely on the ODR and
// on their mangled names, if they're external. // on their mangled names, if they're external.
// TODO: Is there a way to get a program-wide unique name for a // TODO: Is there a way to get a program-wide unique name for a
// decl with local linkage or no linkage? // decl with local linkage or no linkage?
- if (!Features.CPlusPlus || !ETy->getDecl()->isExternallyVisible())+ if (!ETy->getDecl()->isExternallyVisible())
return getChar(); return getChar();
SmallString<256> OutName; SmallString<256> OutName;
clang/lib/CodeGen/Targets/AMDGPU.cpp
@@ -471,20 +471,25 @@ AMDGPUTargetCodeGenInfo::getLLVMSyncScopeID(const LangOptions &LangOpts,
std::string Name; std::string Name;
switch (Scope) { switch (Scope) {
case SyncScope::HIPSingleThread: case SyncScope::HIPSingleThread:
+ case SyncScope::SingleScope:
Name = "singlethread"; Name = "singlethread";
break; break;
case SyncScope::HIPWavefront: case SyncScope::HIPWavefront:
case SyncScope::OpenCLSubGroup: case SyncScope::OpenCLSubGroup:
+ case SyncScope::WavefrontScope:
Name = "wavefront"; Name = "wavefront";
break; break;
case SyncScope::HIPWorkgroup: case SyncScope::HIPWorkgroup:
case SyncScope::OpenCLWorkGroup: case SyncScope::OpenCLWorkGroup:
+ case SyncScope::WorkgroupScope:
Name = "workgroup"; Name = "workgroup";
break; break;
case SyncScope::HIPAgent: case SyncScope::HIPAgent:
case SyncScope::OpenCLDevice: case SyncScope::OpenCLDevice:
+ case SyncScope::DeviceScope:
Name = "agent"; Name = "agent";
break; break;
+ case SyncScope::SystemScope:
case SyncScope::HIPSystem: case SyncScope::HIPSystem:
case SyncScope::OpenCLAllSVMDevices: case SyncScope::OpenCLAllSVMDevices:
Name = ""; Name = "";
clang/lib/Driver/Multilib.cpp
@@ -95,7 +95,7 @@ MultilibSet &MultilibSet::FilterOut(FilterCallback F) {
void MultilibSet::push_back(const Multilib &M) { Multilibs.push_back(M); } void MultilibSet::push_back(const Multilib &M) { Multilibs.push_back(M); }
bool MultilibSet::select(const Multilib::flags_list &Flags, bool MultilibSet::select(const Multilib::flags_list &Flags,
- llvm::SmallVector<Multilib> &Selected) const {+ llvm::SmallVectorImpl<Multilib> &Selected) const {
llvm::StringSet<> FlagSet(expandFlags(Flags)); llvm::StringSet<> FlagSet(expandFlags(Flags));
Selected.clear(); Selected.clear();
clang/lib/Driver/ToolChains/Clang.cpp
@@ -1294,6 +1294,9 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-source-date-epoch"); CmdArgs.push_back("-source-date-epoch");
CmdArgs.push_back(Args.MakeArgString(Epoch)); CmdArgs.push_back(Args.MakeArgString(Epoch));
} }
+
+ Args.addOptInFlag(CmdArgs, options::OPT_fdefine_target_os_macros,
+ options::OPT_fno_define_target_os_macros);
} }
// FIXME: Move to target hook. // FIXME: Move to target hook.
clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -2583,9 +2583,7 @@ void tools::addMachineOutlinerArgs(const Driver &D,
// We only support -moutline in AArch64 and ARM targets right now. If // We only support -moutline in AArch64 and ARM targets right now. If
// we're not compiling for these, emit a warning and ignore the flag. // we're not compiling for these, emit a warning and ignore the flag.
// Otherwise, add the proper mllvm flags. // Otherwise, add the proper mllvm flags.
- if (!(Triple.isARM() || Triple.isThumb() ||+ if (!(Triple.isARM() || Triple.isThumb() || Triple.isAArch64())) {
- Triple.getArch() == llvm::Triple::aarch64 ||
- Triple.getArch() == llvm::Triple::aarch64_32)) {
D.Diag(diag::warn_drv_moutline_unsupported_opt) << Triple.getArchName(); D.Diag(diag::warn_drv_moutline_unsupported_opt) << Triple.getArchName();
} else { } else {
addArg(Twine("-enable-machine-outliner")); addArg(Twine("-enable-machine-outliner"));
clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
@@ -199,9 +199,10 @@ StringRef getLanguageName(Language Lang) {
return "objective-c"; return "objective-c";
case Language::CXX: case Language::CXX:
return "c++"; return "c++";
+ case Language::ObjCXX:
+ return "objective-c++";
// Unsupported language currently // Unsupported language currently
- case Language::ObjCXX:
case Language::OpenCL: case Language::OpenCL:
case Language::OpenCLCXX: case Language::OpenCLCXX:
case Language::CUDA: case Language::CUDA:
clang/lib/Format/ContinuationIndenter.cpp
@@ -1259,7 +1259,7 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
} }
if (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent && if (Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent &&
(Current.is(tok::r_paren) || (Current.is(tok::r_paren) ||
- (Current.is(tok::r_brace) &&+ (Current.is(tok::r_brace) && Current.MatchingParen &&
Current.MatchingParen->is(BK_BracedInit))) && Current.MatchingParen->is(BK_BracedInit))) &&
State.Stack.size() > 1) { State.Stack.size() > 1) {
return State.Stack[State.Stack.size() - 2].LastSpace; return State.Stack[State.Stack.size() - 2].LastSpace;
clang/lib/Format/UnwrappedLineFormatter.cpp
@@ -411,9 +411,16 @@ private:
} }
} }
+ const auto *LastNonComment = TheLine->getLastNonComment();
+ assert(LastNonComment);
+ // FIXME: There are probably cases where we should use LastNonComment
+ // instead of TheLine->Last.
+
// Try to merge a function block with left brace unwrapped. // Try to merge a function block with left brace unwrapped.
- if (TheLine->Last->is(TT_FunctionLBrace) && TheLine->First != TheLine->Last)+ if (LastNonComment->is(TT_FunctionLBrace) &&
+ TheLine->First != LastNonComment) {
return MergeShortFunctions ? tryMergeSimpleBlock(I, E, Limit) : 0; return MergeShortFunctions ? tryMergeSimpleBlock(I, E, Limit) : 0;
+ }
// Try to merge a control statement block with left brace unwrapped. // Try to merge a control statement block with left brace unwrapped.
if (TheLine->Last->is(tok::l_brace) && FirstNonComment != TheLine->Last && if (TheLine->Last->is(tok::l_brace) && FirstNonComment != TheLine->Last &&
FirstNonComment->isOneOf(tok::kw_if, tok::kw_while, tok::kw_for, FirstNonComment->isOneOf(tok::kw_if, tok::kw_while, tok::kw_for,
@@ -789,7 +796,8 @@ private:
} }
} }
- if (Line.Last->is(tok::l_brace)) {+ if (const auto *LastNonComment = Line.getLastNonComment();
+ LastNonComment && LastNonComment->is(tok::l_brace)) {
if (IsSplitBlock && Line.First == Line.Last && if (IsSplitBlock && Line.First == Line.Last &&
I > AnnotatedLines.begin() && I > AnnotatedLines.begin() &&
(I[-1]->endsWith(tok::kw_else) || IsCtrlStmt(*I[-1]))) { (I[-1]->endsWith(tok::kw_else) || IsCtrlStmt(*I[-1]))) {
@@ -805,7 +813,8 @@ private:
if (ShouldMerge()) { if (ShouldMerge()) {
// We merge empty blocks even if the line exceeds the column limit. // We merge empty blocks even if the line exceeds the column limit.
- Tok->SpacesRequiredBefore = Style.SpaceInEmptyBlock ? 1 : 0;+ Tok->SpacesRequiredBefore =
+ (Style.SpaceInEmptyBlock || Line.Last->is(tok::comment)) ? 1 : 0;
Tok->CanBreakBefore = true; Tok->CanBreakBefore = true;
return 1; return 1;
} else if (Limit != 0 && !Line.startsWithNamespace() && } else if (Limit != 0 && !Line.startsWithNamespace() &&
clang/lib/Frontend/CompilerInvocation.cpp
@@ -4365,6 +4365,9 @@ static void GeneratePreprocessorArgs(const PreprocessorOptions &Opts,
if (Opts.SourceDateEpoch) if (Opts.SourceDateEpoch)
GenerateArg(Consumer, OPT_source_date_epoch, Twine(*Opts.SourceDateEpoch)); GenerateArg(Consumer, OPT_source_date_epoch, Twine(*Opts.SourceDateEpoch));
+ if (Opts.DefineTargetOSMacros)
+ GenerateArg(Consumer, OPT_fdefine_target_os_macros);
+
// Don't handle LexEditorPlaceholders. It is implied by the action that is // Don't handle LexEditorPlaceholders. It is implied by the action that is
// generated elsewhere. // generated elsewhere.
} }
@@ -4463,6 +4466,10 @@ static bool ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
if (isStrictlyPreprocessorAction(Action)) if (isStrictlyPreprocessorAction(Action))
Opts.LexEditorPlaceholders = false; Opts.LexEditorPlaceholders = false;
+ Opts.DefineTargetOSMacros =
+ Args.hasFlag(OPT_fdefine_target_os_macros,
+ OPT_fno_define_target_os_macros, Opts.DefineTargetOSMacros);
+
return Diags.getNumErrors() == NumErrorsBefore; return Diags.getNumErrors() == NumErrorsBefore;
} }
clang/lib/Frontend/FrontendActions.cpp
@@ -258,6 +258,16 @@ bool GenerateModuleInterfaceAction::BeginSourceFileAction(
return GenerateModuleAction::BeginSourceFileAction(CI); return GenerateModuleAction::BeginSourceFileAction(CI);
} }
+std::unique_ptr<ASTConsumer>
+GenerateModuleInterfaceAction::CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) {
+ CI.getHeaderSearchOpts().ModulesSkipDiagnosticOptions = true;
+ CI.getHeaderSearchOpts().ModulesSkipHeaderSearchPaths = true;
+ CI.getHeaderSearchOpts().ModulesSkipPragmaDiagnosticMappings = true;
+
+ return GenerateModuleAction::CreateASTConsumer(CI, InFile);
+}
+
std::unique_ptr<raw_pwrite_stream> std::unique_ptr<raw_pwrite_stream>
GenerateModuleInterfaceAction::CreateOutputFile(CompilerInstance &CI, GenerateModuleInterfaceAction::CreateOutputFile(CompilerInstance &CI,
StringRef InFile) { StringRef InFile) {
clang/lib/Frontend/InitPreprocessor.cpp
@@ -809,6 +809,13 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
Builder.defineMacro("__ATOMIC_ACQ_REL", "4"); Builder.defineMacro("__ATOMIC_ACQ_REL", "4");
Builder.defineMacro("__ATOMIC_SEQ_CST", "5"); Builder.defineMacro("__ATOMIC_SEQ_CST", "5");
+ // Define macros for the clang atomic scopes.
+ Builder.defineMacro("__MEMORY_SCOPE_SYSTEM", "0");
+ Builder.defineMacro("__MEMORY_SCOPE_DEVICE", "1");
+ Builder.defineMacro("__MEMORY_SCOPE_WRKGRP", "2");
+ Builder.defineMacro("__MEMORY_SCOPE_WVFRNT", "3");
+ Builder.defineMacro("__MEMORY_SCOPE_SINGLE", "4");
+
// Define macros for the OpenCL memory scope. // Define macros for the OpenCL memory scope.
// The values should match AtomicScopeOpenCLModel::ID enum. // The values should match AtomicScopeOpenCLModel::ID enum.
static_assert( static_assert(
@@ -1344,6 +1351,15 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
if (TI.getTriple().isOSBinFormatELF()) if (TI.getTriple().isOSBinFormatELF())
Builder.defineMacro("__ELF__"); Builder.defineMacro("__ELF__");
+ // Target OS macro definitions.
+ if (PPOpts.DefineTargetOSMacros) {
+ const llvm::Triple &Triple = TI.getTriple();
+#define TARGET_OS(Name, Predicate) \
+ Builder.defineMacro(#Name, (Predicate) ? "1" : "0");
+#include "clang/Basic/TargetOSMacros.def"
+#undef TARGET_OS
+ }
+
// Get other target #defines. // Get other target #defines.
TI.getTargetDefines(LangOpts, Builder); TI.getTargetDefines(LangOpts, Builder);
} }
clang/lib/Lex/HeaderSearch.cpp
@@ -105,7 +105,7 @@ void HeaderSearch::PrintStats() {
void HeaderSearch::SetSearchPaths( void HeaderSearch::SetSearchPaths(
std::vector<DirectoryLookup> dirs, unsigned int angledDirIdx, std::vector<DirectoryLookup> dirs, unsigned int angledDirIdx,
- unsigned int systemDirIdx, bool noCurDirSearch,+ unsigned int systemDirIdx,
llvm::DenseMap<unsigned int, unsigned int> searchDirToHSEntry) { llvm::DenseMap<unsigned int, unsigned int> searchDirToHSEntry) {
assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() && assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() &&
"Directory indices are unordered"); "Directory indices are unordered");
@@ -113,7 +113,6 @@ void HeaderSearch::SetSearchPaths(
SearchDirsUsage.assign(SearchDirs.size(), false); SearchDirsUsage.assign(SearchDirs.size(), false);
AngledDirIdx = angledDirIdx; AngledDirIdx = angledDirIdx;
SystemDirIdx = systemDirIdx; SystemDirIdx = systemDirIdx;
- NoCurDirSearch = noCurDirSearch;
SearchDirToHSEntry = std::move(searchDirToHSEntry); SearchDirToHSEntry = std::move(searchDirToHSEntry);
//LookupFileCache.clear(); //LookupFileCache.clear();
indexInitialHeaderMaps(); indexInitialHeaderMaps();
@@ -904,12 +903,12 @@ OptionalFileEntryRef HeaderSearch::LookupFile(
ModuleMap::KnownHeader MSSuggestedModule; ModuleMap::KnownHeader MSSuggestedModule;
OptionalFileEntryRef MSFE; OptionalFileEntryRef MSFE;
- // Unless disabled, check to see if the file is in the #includer's+ // Check to see if the file is in the #includer's directory. This cannot be
- // directory. This cannot be based on CurDir, because each includer could be+ // based on CurDir, because each includer could be a #include of a
- // a #include of a subdirectory (#include "foo/bar.h") and a subsequent+ // subdirectory (#include "foo/bar.h") and a subsequent include of "baz.h"
- // include of "baz.h" should resolve to "whatever/foo/baz.h".+ // should resolve to "whatever/foo/baz.h". This search is not done for <>
- // This search is not done for <> headers.+ // headers.
- if (!Includers.empty() && !isAngled && !NoCurDirSearch) {+ if (!Includers.empty() && !isAngled) {
SmallString<1024> TmpDir; SmallString<1024> TmpDir;
bool First = true; bool First = true;
for (const auto &IncluderAndDir : Includers) { for (const auto &IncluderAndDir : Includers) {
clang/lib/Lex/InitHeaderSearch.cpp
@@ -513,9 +513,8 @@ void InitHeaderSearch::Realize(const LangOptions &Lang) {
unsigned NonSystemRemoved = RemoveDuplicates(SearchList, NumQuoted, Verbose); unsigned NonSystemRemoved = RemoveDuplicates(SearchList, NumQuoted, Verbose);
NumAngled -= NonSystemRemoved; NumAngled -= NonSystemRemoved;
- bool DontSearchCurDir = false; // TODO: set to true if -I- is set?
Headers.SetSearchPaths(extractLookups(SearchList), NumQuoted, NumAngled, Headers.SetSearchPaths(extractLookups(SearchList), NumQuoted, NumAngled,
- DontSearchCurDir, mapToUserEntries(SearchList));+ mapToUserEntries(SearchList));
Headers.SetSystemHeaderPrefixes(SystemHeaderPrefixes); Headers.SetSystemHeaderPrefixes(SystemHeaderPrefixes);
clang/lib/Parse/ParseOpenACC.cpp
@@ -56,6 +56,7 @@ OpenACCDirectiveKindEx getOpenACCDirectiveKind(Token Tok) {
.Case("shutdown", OpenACCDirectiveKind::Shutdown) .Case("shutdown", OpenACCDirectiveKind::Shutdown)
.Case("set", OpenACCDirectiveKind::Shutdown) .Case("set", OpenACCDirectiveKind::Shutdown)
.Case("update", OpenACCDirectiveKind::Update) .Case("update", OpenACCDirectiveKind::Update)
+ .Case("wait", OpenACCDirectiveKind::Wait)
.Default(OpenACCDirectiveKind::Invalid); .Default(OpenACCDirectiveKind::Invalid);
if (DirKind != OpenACCDirectiveKind::Invalid) if (DirKind != OpenACCDirectiveKind::Invalid)
@@ -82,6 +83,27 @@ OpenACCAtomicKind getOpenACCAtomicKind(Token Tok) {
.Default(OpenACCAtomicKind::Invalid); .Default(OpenACCAtomicKind::Invalid);
} }
+enum class OpenACCSpecialTokenKind {
+ ReadOnly,
+ DevNum,
+ Queues,
+};
+
+bool isOpenACCSpecialToken(OpenACCSpecialTokenKind Kind, Token Tok) {
+ if (!Tok.is(tok::identifier))
+ return false;
+
+ switch (Kind) {
+ case OpenACCSpecialTokenKind::ReadOnly:
+ return Tok.getIdentifierInfo()->isStr("readonly");
+ case OpenACCSpecialTokenKind::DevNum:
+ return Tok.getIdentifierInfo()->isStr("devnum");
+ case OpenACCSpecialTokenKind::Queues:
+ return Tok.getIdentifierInfo()->isStr("queues");
+ }
+ llvm_unreachable("Unknown 'Kind' Passed");
+}
+
bool isOpenACCDirectiveKind(OpenACCDirectiveKind Kind, Token Tok) { bool isOpenACCDirectiveKind(OpenACCDirectiveKind Kind, Token Tok) {
if (!Tok.is(tok::identifier)) if (!Tok.is(tok::identifier))
return false; return false;
@@ -123,6 +145,8 @@ bool isOpenACCDirectiveKind(OpenACCDirectiveKind Kind, Token Tok) {
return Tok.getIdentifierInfo()->isStr("set"); return Tok.getIdentifierInfo()->isStr("set");
case OpenACCDirectiveKind::Update: case OpenACCDirectiveKind::Update:
return Tok.getIdentifierInfo()->isStr("update"); return Tok.getIdentifierInfo()->isStr("update");
+ case OpenACCDirectiveKind::Wait:
+ return Tok.getIdentifierInfo()->isStr("wait");
case OpenACCDirectiveKind::Invalid: case OpenACCDirectiveKind::Invalid:
return false; return false;
} }
@@ -182,7 +206,7 @@ OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) {
// Just #pragma acc can get us immediately to the end, make sure we don't // Just #pragma acc can get us immediately to the end, make sure we don't
// introspect on the spelling before then. // introspect on the spelling before then.
- if (FirstTok.isAnnotation()) {+ if (FirstTok.isNot(tok::identifier)) {
P.Diag(FirstTok, diag::err_acc_missing_directive); P.Diag(FirstTok, diag::err_acc_missing_directive);
return OpenACCDirectiveKind::Invalid; return OpenACCDirectiveKind::Invalid;
} }
@@ -200,11 +224,8 @@ OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) {
if (ExDirKind >= OpenACCDirectiveKindEx::Invalid) { if (ExDirKind >= OpenACCDirectiveKindEx::Invalid) {
switch (ExDirKind) { switch (ExDirKind) {
case OpenACCDirectiveKindEx::Invalid: { case OpenACCDirectiveKindEx::Invalid: {
- if (!FirstTok.is(tok::identifier))+ P.Diag(FirstTok, diag::err_acc_invalid_directive)
- P.Diag(FirstTok, diag::err_expected) << tok::identifier;+ << 0 << FirstTok.getIdentifierInfo();
- else
- P.Diag(FirstTok, diag::err_acc_invalid_directive)
- << 0 << FirstTok.getIdentifierInfo();
return OpenACCDirectiveKind::Invalid; return OpenACCDirectiveKind::Invalid;
} }
case OpenACCDirectiveKindEx::Enter: case OpenACCDirectiveKindEx::Enter:
@@ -251,6 +272,67 @@ void ParseOpenACCClauseList(Parser &P) {
} // namespace } // namespace
+/// OpenACC 3.3, section 2.16:
+/// In this section and throughout the specification, the term wait-argument
+/// means:
+/// [ devnum : int-expr : ] [ queues : ] async-argument-list
+bool Parser::ParseOpenACCWaitArgument() {
+ // [devnum : int-expr : ]
+ if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::DevNum, Tok) &&
+ NextToken().is(tok::colon)) {
+ // Consume devnum.
+ ConsumeToken();
+ // Consume colon.
+ ConsumeToken();
+
+ ExprResult IntExpr =
+ getActions().CorrectDelayedTyposInExpr(ParseAssignmentExpression());
+ if (IntExpr.isInvalid())
+ return true;
+
+ if (ExpectAndConsume(tok::colon))
+ return true;
+ }
+
+ // [ queues : ]
+ if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::Queues, Tok) &&
+ NextToken().is(tok::colon)) {
+ // Consume queues.
+ ConsumeToken();
+ // Consume colon.
+ ConsumeToken();
+ }
+
+ // OpenACC 3.3, section 2.16:
+ // the term 'async-argument' means a nonnegative scalar integer expression, or
+ // one of the special values 'acc_async_noval' or 'acc_async_sync', as defined
+ // in the C header file and the Fortran opacc module.
+ //
+ // We are parsing this simply as list of assignment expressions (to avoid
+ // comma being troublesome), and will ensure it is an integral type. The
+ // 'special' types are defined as macros, so we can't really check those
+ // (other than perhaps as values at one point?), but the standard does say it
+ // is implementation-defined to use any other negative value.
+ //
+ //
+ bool FirstArg = true;
+ while (!getCurToken().isOneOf(tok::r_paren, tok::annot_pragma_openacc_end)) {
+ if (!FirstArg) {
+ if (ExpectAndConsume(tok::comma))
+ return true;
+ }
+ FirstArg = false;
+
+ ExprResult CurArg =
+ getActions().CorrectDelayedTyposInExpr(ParseAssignmentExpression());
+
+ if (CurArg.isInvalid())
+ return true;
+ }
+
+ return false;
+}
+
ExprResult Parser::ParseOpenACCIDExpression() { ExprResult Parser::ParseOpenACCIDExpression() {
ExprResult Res; ExprResult Res;
if (getLangOpts().CPlusPlus) { if (getLangOpts().CPlusPlus) {
@@ -340,8 +422,7 @@ void Parser::ParseOpenACCCacheVarList() {
// specifications. First, see if we have `readonly:`, else we back-out and // specifications. First, see if we have `readonly:`, else we back-out and
// treat it like the beginning of a reference to a potentially-existing // treat it like the beginning of a reference to a potentially-existing
// `readonly` variable. // `readonly` variable.
- if (getCurToken().is(tok::identifier) &&+ if (isOpenACCSpecialToken(OpenACCSpecialTokenKind::ReadOnly, Tok) &&
- getCurToken().getIdentifierInfo()->isStr("readonly") &&
NextToken().is(tok::colon)) { NextToken().is(tok::colon)) {
// Consume both tokens. // Consume both tokens.
ConsumeToken(); ConsumeToken();
@@ -399,6 +480,13 @@ void Parser::ParseOpenACCDirective() {
// so we can always consume the close. // so we can always consume the close.
T.consumeClose(); T.consumeClose();
break; break;
+ case OpenACCDirectiveKind::Wait:
+ // OpenACC has an optional paren-wrapped 'wait-argument'.
+ if (ParseOpenACCWaitArgument())
+ T.skipToEnd();
+ else
+ T.consumeClose();
+ break;
} }
} else if (DirKind == OpenACCDirectiveKind::Cache) { } else if (DirKind == OpenACCDirectiveKind::Cache) {
// Cache's paren var-list is required, so error here if it isn't provided. // Cache's paren var-list is required, so error here if it isn't provided.
clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -306,6 +306,7 @@ struct BuiltinTypeDeclBuilder {
} }
TemplateParameterListBuilder addTemplateArgumentList(); TemplateParameterListBuilder addTemplateArgumentList();
+ BuiltinTypeDeclBuilder &addSimpleTemplateParams(ArrayRef<StringRef> Names);
}; };
struct TemplateParameterListBuilder { struct TemplateParameterListBuilder {
@@ -360,11 +361,19 @@ struct TemplateParameterListBuilder {
return Builder; return Builder;
} }
}; };
+} // namespace
TemplateParameterListBuilder BuiltinTypeDeclBuilder::addTemplateArgumentList() { TemplateParameterListBuilder BuiltinTypeDeclBuilder::addTemplateArgumentList() {
return TemplateParameterListBuilder(*this); return TemplateParameterListBuilder(*this);
} }
-} // namespace+
+BuiltinTypeDeclBuilder &
+BuiltinTypeDeclBuilder::addSimpleTemplateParams(ArrayRef<StringRef> Names) {
+ TemplateParameterListBuilder Builder = this->addTemplateArgumentList();
+ for (StringRef Name : Names)
+ Builder.addTypeParameter(Name);
+ return Builder.finalizeTemplateArgs();
+}
HLSLExternalSemaSource::~HLSLExternalSemaSource() {} HLSLExternalSemaSource::~HLSLExternalSemaSource() {}
@@ -390,7 +399,7 @@ void HLSLExternalSemaSource::InitializeSema(Sema &S) {
// Force external decls in the HLSL namespace to load from the PCH. // Force external decls in the HLSL namespace to load from the PCH.
(void)HLSLNamespace->getCanonicalDecl()->decls_begin(); (void)HLSLNamespace->getCanonicalDecl()->decls_begin();
defineTrivialHLSLTypes(); defineTrivialHLSLTypes();
- forwardDeclareHLSLTypes();+ defineHLSLTypesWithForwardDeclarations();
// This adds a `using namespace hlsl` directive. In DXC, we don't put HLSL's // This adds a `using namespace hlsl` directive. In DXC, we don't put HLSL's
// built in types inside a namespace, but we are planning to change that in // built in types inside a namespace, but we are planning to change that in
@@ -467,18 +476,32 @@ void HLSLExternalSemaSource::defineTrivialHLSLTypes() {
.Record; .Record;
} }
-void HLSLExternalSemaSource::forwardDeclareHLSLTypes() {+/// Set up common members and attributes for buffer types
+static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S,
+ ResourceClass RC,
+ ResourceKind RK) {
+ return BuiltinTypeDeclBuilder(Decl)
+ .addHandleMember()
+ .addDefaultHandleConstructor(S, RC)
+ .annotateResourceClass(RC, RK);
+}
+
+void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
CXXRecordDecl *Decl; CXXRecordDecl *Decl;
Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer")
- .addTemplateArgumentList()+ .addSimpleTemplateParams({"element_type"})
- .addTypeParameter("element_type", SemaPtr->getASTContext().FloatTy)
- .finalizeTemplateArgs()
.Record; .Record;
- if (!Decl->isCompleteDefinition())+ onCompletion(Decl, [this](CXXRecordDecl *Decl) {
- Completions.insert(+ setupBufferType(Decl, *SemaPtr, ResourceClass::UAV,
- std::make_pair(Decl->getCanonicalDecl(),+ ResourceKind::TypedBuffer)
- std::bind(&HLSLExternalSemaSource::completeBufferType,+ .addArraySubscriptOperators()
- this, std::placeholders::_1)));+ .completeDefinition();
+ });
+}
+
+void HLSLExternalSemaSource::onCompletion(CXXRecordDecl *Record,
+ CompletionFunction Fn) {
+ Completions.insert(std::make_pair(Record->getCanonicalDecl(), Fn));
} }
void HLSLExternalSemaSource::CompleteType(TagDecl *Tag) { void HLSLExternalSemaSource::CompleteType(TagDecl *Tag) {
@@ -496,12 +519,3 @@ void HLSLExternalSemaSource::CompleteType(TagDecl *Tag) {
return; return;
It->second(Record); It->second(Record);
} }
-
-void HLSLExternalSemaSource::completeBufferType(CXXRecordDecl *Record) {
- BuiltinTypeDeclBuilder(Record)
- .addHandleMember()
- .addDefaultHandleConstructor(*SemaPtr, ResourceClass::UAV)
- .addArraySubscriptOperators()
- .annotateResourceClass(ResourceClass::UAV, ResourceKind::TypedBuffer)
- .completeDefinition();
-}
clang/lib/Sema/SemaChecking.cpp
@@ -7653,6 +7653,8 @@ static bool isValidOrderingForOp(int64_t Ordering, AtomicExpr::AtomicOp Op) {
case AtomicExpr::AO__hip_atomic_load: case AtomicExpr::AO__hip_atomic_load:
case AtomicExpr::AO__atomic_load_n: case AtomicExpr::AO__atomic_load_n:
case AtomicExpr::AO__atomic_load: case AtomicExpr::AO__atomic_load:
+ case AtomicExpr::AO__scoped_atomic_load_n:
+ case AtomicExpr::AO__scoped_atomic_load:
return OrderingCABI != llvm::AtomicOrderingCABI::release && return OrderingCABI != llvm::AtomicOrderingCABI::release &&
OrderingCABI != llvm::AtomicOrderingCABI::acq_rel; OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
@@ -7661,6 +7663,8 @@ static bool isValidOrderingForOp(int64_t Ordering, AtomicExpr::AtomicOp Op) {
case AtomicExpr::AO__hip_atomic_store: case AtomicExpr::AO__hip_atomic_store:
case AtomicExpr::AO__atomic_store: case AtomicExpr::AO__atomic_store:
case AtomicExpr::AO__atomic_store_n: case AtomicExpr::AO__atomic_store_n:
+ case AtomicExpr::AO__scoped_atomic_store:
+ case AtomicExpr::AO__scoped_atomic_store_n:
return OrderingCABI != llvm::AtomicOrderingCABI::consume && return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
OrderingCABI != llvm::AtomicOrderingCABI::acquire && OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
OrderingCABI != llvm::AtomicOrderingCABI::acq_rel; OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
@@ -7737,13 +7741,19 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange,
Op <= AtomicExpr::AO__opencl_atomic_fetch_max; Op <= AtomicExpr::AO__opencl_atomic_fetch_max;
bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_load && bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_load &&
Op <= AtomicExpr::AO__hip_atomic_fetch_max; Op <= AtomicExpr::AO__hip_atomic_fetch_max;
+ bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_load &&
+ Op <= AtomicExpr::AO__scoped_atomic_fetch_max;
bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_init && bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_init &&
Op <= AtomicExpr::AO__c11_atomic_fetch_min) || Op <= AtomicExpr::AO__c11_atomic_fetch_min) ||
IsOpenCL; IsOpenCL;
bool IsN = Op == AtomicExpr::AO__atomic_load_n || bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
Op == AtomicExpr::AO__atomic_store_n || Op == AtomicExpr::AO__atomic_store_n ||
Op == AtomicExpr::AO__atomic_exchange_n || Op == AtomicExpr::AO__atomic_exchange_n ||
- Op == AtomicExpr::AO__atomic_compare_exchange_n;+ Op == AtomicExpr::AO__atomic_compare_exchange_n ||
+ Op == AtomicExpr::AO__scoped_atomic_load_n ||
+ Op == AtomicExpr::AO__scoped_atomic_store_n ||
+ Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
+ Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
// Bit mask for extra allowed value types other than integers for atomic // Bit mask for extra allowed value types other than integers for atomic
// arithmetic operations. Add/sub allow pointer and floating point. Min/max // arithmetic operations. Add/sub allow pointer and floating point. Min/max
// allow floating point. // allow floating point.
@@ -7764,10 +7774,12 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange,
case AtomicExpr::AO__opencl_atomic_load: case AtomicExpr::AO__opencl_atomic_load:
case AtomicExpr::AO__hip_atomic_load: case AtomicExpr::AO__hip_atomic_load:
case AtomicExpr::AO__atomic_load_n: case AtomicExpr::AO__atomic_load_n:
+ case AtomicExpr::AO__scoped_atomic_load_n:
Form = Load; Form = Load;
break; break;
case AtomicExpr::AO__atomic_load: case AtomicExpr::AO__atomic_load:
+ case AtomicExpr::AO__scoped_atomic_load:
Form = LoadCopy; Form = LoadCopy;
break; break;
@@ -7776,12 +7788,18 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange,
case AtomicExpr::AO__hip_atomic_store: case AtomicExpr::AO__hip_atomic_store:
case AtomicExpr::AO__atomic_store: case AtomicExpr::AO__atomic_store:
case AtomicExpr::AO__atomic_store_n: case AtomicExpr::AO__atomic_store_n:
+ case AtomicExpr::AO__scoped_atomic_store:
+ case AtomicExpr::AO__scoped_atomic_store_n:
Form = Copy; Form = Copy;
break; break;
case AtomicExpr::AO__atomic_fetch_add: case AtomicExpr::AO__atomic_fetch_add:
case AtomicExpr::AO__atomic_fetch_sub: case AtomicExpr::AO__atomic_fetch_sub:
case AtomicExpr::AO__atomic_add_fetch: case AtomicExpr::AO__atomic_add_fetch:
case AtomicExpr::AO__atomic_sub_fetch: case AtomicExpr::AO__atomic_sub_fetch:
+ case AtomicExpr::AO__scoped_atomic_fetch_add:
+ case AtomicExpr::AO__scoped_atomic_fetch_sub:
+ case AtomicExpr::AO__scoped_atomic_add_fetch:
+ case AtomicExpr::AO__scoped_atomic_sub_fetch:
case AtomicExpr::AO__c11_atomic_fetch_add: case AtomicExpr::AO__c11_atomic_fetch_add:
case AtomicExpr::AO__c11_atomic_fetch_sub: case AtomicExpr::AO__c11_atomic_fetch_sub:
case AtomicExpr::AO__opencl_atomic_fetch_add: case AtomicExpr::AO__opencl_atomic_fetch_add:
@@ -7795,6 +7813,10 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange,
case AtomicExpr::AO__atomic_fetch_min: case AtomicExpr::AO__atomic_fetch_min:
case AtomicExpr::AO__atomic_max_fetch: case AtomicExpr::AO__atomic_max_fetch:
case AtomicExpr::AO__atomic_min_fetch: case AtomicExpr::AO__atomic_min_fetch:
+ case AtomicExpr::AO__scoped_atomic_fetch_max:
+ case AtomicExpr::AO__scoped_atomic_fetch_min:
+ case AtomicExpr::AO__scoped_atomic_max_fetch:
+ case AtomicExpr::AO__scoped_atomic_min_fetch:
case AtomicExpr::AO__c11_atomic_fetch_max: case AtomicExpr::AO__c11_atomic_fetch_max:
case AtomicExpr::AO__c11_atomic_fetch_min: case AtomicExpr::AO__c11_atomic_fetch_min:
case AtomicExpr::AO__opencl_atomic_fetch_max: case AtomicExpr::AO__opencl_atomic_fetch_max:
@@ -7822,6 +7844,14 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange,
case AtomicExpr::AO__atomic_or_fetch: case AtomicExpr::AO__atomic_or_fetch:
case AtomicExpr::AO__atomic_xor_fetch: case AtomicExpr::AO__atomic_xor_fetch:
case AtomicExpr::AO__atomic_nand_fetch: case AtomicExpr::AO__atomic_nand_fetch:
+ case AtomicExpr::AO__scoped_atomic_fetch_and:
+ case AtomicExpr::AO__scoped_atomic_fetch_or:
+ case AtomicExpr::AO__scoped_atomic_fetch_xor:
+ case AtomicExpr::AO__scoped_atomic_fetch_nand:
+ case AtomicExpr::AO__scoped_atomic_and_fetch:
+ case AtomicExpr::AO__scoped_atomic_or_fetch:
+ case AtomicExpr::AO__scoped_atomic_xor_fetch:
+ case AtomicExpr::AO__scoped_atomic_nand_fetch:
Form = Arithmetic; Form = Arithmetic;
break; break;
@@ -7829,10 +7859,12 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange,
case AtomicExpr::AO__hip_atomic_exchange: case AtomicExpr::AO__hip_atomic_exchange:
case AtomicExpr::AO__opencl_atomic_exchange: case AtomicExpr::AO__opencl_atomic_exchange:
case AtomicExpr::AO__atomic_exchange_n: case AtomicExpr::AO__atomic_exchange_n:
+ case AtomicExpr::AO__scoped_atomic_exchange_n:
Form = Xchg; Form = Xchg;
break; break;
case AtomicExpr::AO__atomic_exchange: case AtomicExpr::AO__atomic_exchange:
+ case AtomicExpr::AO__scoped_atomic_exchange:
Form = GNUXchg; Form = GNUXchg;
break; break;
@@ -7847,12 +7879,15 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange,
case AtomicExpr::AO__atomic_compare_exchange: case AtomicExpr::AO__atomic_compare_exchange:
case AtomicExpr::AO__atomic_compare_exchange_n: case AtomicExpr::AO__atomic_compare_exchange_n:
+ case AtomicExpr::AO__scoped_atomic_compare_exchange:
+ case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
Form = GNUCmpXchg; Form = GNUCmpXchg;
break; break;
} }
unsigned AdjustedNumArgs = NumArgs[Form]; unsigned AdjustedNumArgs = NumArgs[Form];
- if ((IsOpenCL || IsHIP) && Op != AtomicExpr::AO__opencl_atomic_init)+ if ((IsOpenCL || IsHIP || IsScoped) &&
+ Op != AtomicExpr::AO__opencl_atomic_init)
++AdjustedNumArgs; ++AdjustedNumArgs;
// Check we have the right number of arguments. // Check we have the right number of arguments.
if (Args.size() < AdjustedNumArgs) { if (Args.size() < AdjustedNumArgs) {
clang/lib/Sema/SemaInit.cpp
@@ -4085,16 +4085,13 @@ static bool hasCopyOrMoveCtorParam(ASTContext &Ctx,
return Ctx.hasSameUnqualifiedType(ParmT, ClassT); return Ctx.hasSameUnqualifiedType(ParmT, ClassT);
} }
-static OverloadingResult+static OverloadingResult ResolveConstructorOverload(
-ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc,+ Sema &S, SourceLocation DeclLoc, MultiExprArg Args,
- MultiExprArg Args,+ OverloadCandidateSet &CandidateSet, QualType DestType,
- OverloadCandidateSet &CandidateSet,+ DeclContext::lookup_result Ctors, OverloadCandidateSet::iterator &Best,
- QualType DestType,+ bool CopyInitializing, bool AllowExplicit, bool OnlyListConstructors,
- DeclContext::lookup_result Ctors,+ bool IsListInit, bool RequireActualConstructor,
- OverloadCandidateSet::iterator &Best,+ bool SecondStepOfCopyInit = false) {
- bool CopyInitializing, bool AllowExplicit,
- bool OnlyListConstructors, bool IsListInit,
- bool SecondStepOfCopyInit = false) {
CandidateSet.clear(OverloadCandidateSet::CSK_InitByConstructor); CandidateSet.clear(OverloadCandidateSet::CSK_InitByConstructor);
CandidateSet.setDestAS(DestType.getQualifiers().getAddressSpace()); CandidateSet.setDestAS(DestType.getQualifiers().getAddressSpace());
@@ -4157,7 +4154,7 @@ ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc,
// Note: SecondStepOfCopyInit is only ever true in this case when // Note: SecondStepOfCopyInit is only ever true in this case when
// evaluating whether to produce a C++98 compatibility warning. // evaluating whether to produce a C++98 compatibility warning.
if (S.getLangOpts().CPlusPlus17 && Args.size() == 1 && if (S.getLangOpts().CPlusPlus17 && Args.size() == 1 &&
- !SecondStepOfCopyInit) {+ !RequireActualConstructor && !SecondStepOfCopyInit) {
Expr *Initializer = Args[0]; Expr *Initializer = Args[0];
auto *SourceRD = Initializer->getType()->getAsCXXRecordDecl(); auto *SourceRD = Initializer->getType()->getAsCXXRecordDecl();
if (SourceRD && S.isCompleteType(DeclLoc, Initializer->getType())) { if (SourceRD && S.isCompleteType(DeclLoc, Initializer->getType())) {
@@ -4225,6 +4222,12 @@ static void TryConstructorInitialization(Sema &S,
return; return;
} }
+ bool RequireActualConstructor =
+ !(Entity.getKind() != InitializedEntity::EK_Base &&
+ Entity.getKind() != InitializedEntity::EK_Delegating &&
+ Entity.getKind() !=
+ InitializedEntity::EK_LambdaToBlockConversionBlockElement);
+
// C++17 [dcl.init]p17: // C++17 [dcl.init]p17:
// - If the initializer expression is a prvalue and the cv-unqualified // - If the initializer expression is a prvalue and the cv-unqualified
// version of the source type is the same class as the class of the // version of the source type is the same class as the class of the
@@ -4234,11 +4237,7 @@ static void TryConstructorInitialization(Sema &S,
// class or delegating to another constructor from a mem-initializer. // class or delegating to another constructor from a mem-initializer.
// ObjC++: Lambda captured by the block in the lambda to block conversion // ObjC++: Lambda captured by the block in the lambda to block conversion
// should avoid copy elision. // should avoid copy elision.
- if (S.getLangOpts().CPlusPlus17 &&+ if (S.getLangOpts().CPlusPlus17 && !RequireActualConstructor &&
- Entity.getKind() != InitializedEntity::EK_Base &&
- Entity.getKind() != InitializedEntity::EK_Delegating &&
- Entity.getKind() !=
- InitializedEntity::EK_LambdaToBlockConversionBlockElement &&
UnwrappedArgs.size() == 1 && UnwrappedArgs[0]->isPRValue() && UnwrappedArgs.size() == 1 && UnwrappedArgs[0]->isPRValue() &&
S.Context.hasSameUnqualifiedType(UnwrappedArgs[0]->getType(), DestType)) { S.Context.hasSameUnqualifiedType(UnwrappedArgs[0]->getType(), DestType)) {
// Convert qualifications if necessary. // Convert qualifications if necessary.
@@ -4286,11 +4285,10 @@ static void TryConstructorInitialization(Sema &S,
// If the initializer list has no elements and T has a default constructor, // If the initializer list has no elements and T has a default constructor,
// the first phase is omitted. // the first phase is omitted.
if (!(UnwrappedArgs.empty() && S.LookupDefaultConstructor(DestRecordDecl))) if (!(UnwrappedArgs.empty() && S.LookupDefaultConstructor(DestRecordDecl)))
- Result = ResolveConstructorOverload(S, Kind.getLocation(), Args,+ Result = ResolveConstructorOverload(
- CandidateSet, DestType, Ctors, Best,+ S, Kind.getLocation(), Args, CandidateSet, DestType, Ctors, Best,
- CopyInitialization, AllowExplicit,+ CopyInitialization, AllowExplicit,
- /*OnlyListConstructors=*/true,+ /*OnlyListConstructors=*/true, IsListInit, RequireActualConstructor);
- IsListInit);
} }
// C++11 [over.match.list]p1: // C++11 [over.match.list]p1:
@@ -4300,11 +4298,10 @@ static void TryConstructorInitialization(Sema &S,
// elements of the initializer list. // elements of the initializer list.
if (Result == OR_No_Viable_Function) { if (Result == OR_No_Viable_Function) {
AsInitializerList = false; AsInitializerList = false;
- Result = ResolveConstructorOverload(S, Kind.getLocation(), UnwrappedArgs,+ Result = ResolveConstructorOverload(
- CandidateSet, DestType, Ctors, Best,+ S, Kind.getLocation(), UnwrappedArgs, CandidateSet, DestType, Ctors,
- CopyInitialization, AllowExplicit,+ Best, CopyInitialization, AllowExplicit,
- /*OnlyListConstructors=*/false,+ /*OnlyListConstructors=*/false, IsListInit, RequireActualConstructor);
- IsListInit);
} }
if (Result) { if (Result) {
Sequence.SetOverloadFailure( Sequence.SetOverloadFailure(
@@ -6778,6 +6775,7 @@ static ExprResult CopyObject(Sema &S,
S, Loc, CurInitExpr, CandidateSet, T, Ctors, Best, S, Loc, CurInitExpr, CandidateSet, T, Ctors, Best,
/*CopyInitializing=*/false, /*AllowExplicit=*/true, /*CopyInitializing=*/false, /*AllowExplicit=*/true,
/*OnlyListConstructors=*/false, /*IsListInit=*/false, /*OnlyListConstructors=*/false, /*IsListInit=*/false,
+ /*RequireActualConstructor=*/false,
/*SecondStepOfCopyInit=*/true)) { /*SecondStepOfCopyInit=*/true)) {
case OR_Success: case OR_Success:
break; break;
@@ -6920,6 +6918,7 @@ static void CheckCXX98CompatAccessibleCopy(Sema &S,
S, Loc, CurInitExpr, CandidateSet, CurInitExpr->getType(), Ctors, Best, S, Loc, CurInitExpr, CandidateSet, CurInitExpr->getType(), Ctors, Best,
/*CopyInitializing=*/false, /*AllowExplicit=*/true, /*CopyInitializing=*/false, /*AllowExplicit=*/true,
/*OnlyListConstructors=*/false, /*IsListInit=*/false, /*OnlyListConstructors=*/false, /*IsListInit=*/false,
+ /*RequireActualConstructor=*/false,
/*SecondStepOfCopyInit=*/true); /*SecondStepOfCopyInit=*/true);
PartialDiagnostic Diag = S.PDiag(diag::warn_cxx98_compat_temp_copy) PartialDiagnostic Diag = S.PDiag(diag::warn_cxx98_compat_temp_copy)
clang/lib/Sema/SemaStmt.cpp
@@ -1327,6 +1327,9 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
} }
} }
+ if (!TheDefaultStmt)
+ Diag(SwitchLoc, diag::warn_switch_default);
+
if (!HasDependentValue) { if (!HasDependentValue) {
// If we don't have a default statement, check whether the // If we don't have a default statement, check whether the
// condition is constant. // condition is constant.
clang/lib/Sema/SemaTemplate.cpp
@@ -1712,6 +1712,8 @@ class ConstraintRefersToContainingTemplateChecker
// Friend, likely because it was referred to without its template arguments. // Friend, likely because it was referred to without its template arguments.
void CheckIfContainingRecord(const CXXRecordDecl *CheckingRD) { void CheckIfContainingRecord(const CXXRecordDecl *CheckingRD) {
CheckingRD = CheckingRD->getMostRecentDecl(); CheckingRD = CheckingRD->getMostRecentDecl();
+ if (!CheckingRD->isTemplated())
+ return;
for (const DeclContext *DC = Friend->getLexicalDeclContext(); for (const DeclContext *DC = Friend->getLexicalDeclContext();
DC && !DC->isFileContext(); DC = DC->getParent()) DC && !DC->isFileContext(); DC = DC->getParent())
clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -810,6 +810,10 @@ void Sema::PrintInstantiationStack() {
Diags.Report(Active->PointOfInstantiation, Diags.Report(Active->PointOfInstantiation,
diag::note_template_nsdmi_here) diag::note_template_nsdmi_here)
<< FD << Active->InstantiationRange; << FD << Active->InstantiationRange;
+ } else if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(D)) {
+ Diags.Report(Active->PointOfInstantiation,
+ diag::note_template_class_instantiation_here)
+ << CTD << Active->InstantiationRange;
} else { } else {
Diags.Report(Active->PointOfInstantiation, Diags.Report(Active->PointOfInstantiation,
diag::note_template_type_alias_instantiation_here) diag::note_template_type_alias_instantiation_here)
clang/lib/StaticAnalyzer/Checkers/BitwiseShiftChecker.cpp
@@ -344,7 +344,7 @@ BitwiseShiftValidator::createBugReport(StringRef ShortMsg, StringRef Msg) const
} // anonymous namespace } // anonymous namespace
class BitwiseShiftChecker : public Checker<check::PreStmt<BinaryOperator>> { class BitwiseShiftChecker : public Checker<check::PreStmt<BinaryOperator>> {
- mutable std::unique_ptr<BugType> BTPtr;+ BugType BT{this, "Bitwise shift", "Suspicious operation"};
public: public:
void checkPreStmt(const BinaryOperator *B, CheckerContext &Ctx) const { void checkPreStmt(const BinaryOperator *B, CheckerContext &Ctx) const {
@@ -353,11 +353,7 @@ public:
if (Op != BO_Shl && Op != BO_Shr) if (Op != BO_Shl && Op != BO_Shr)
return; return;
- if (!BTPtr)+ BitwiseShiftValidator(B, Ctx, BT, Pedantic).run();
- BTPtr = std::make_unique<BugType>(this, "Bitwise shift",
- "Suspicious operation");
-
- BitwiseShiftValidator(B, Ctx, *BTPtr, Pedantic).run();
} }
bool Pedantic = false; bool Pedantic = false;
clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
@@ -22,10 +22,12 @@
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "llvm/Support/FormatVariadic.h"
#include <optional> #include <optional>
using namespace clang; using namespace clang;
using namespace ento; using namespace ento;
+using llvm::formatv;
namespace { namespace {
// This evaluator checks two SVals for equality. The first SVal is provided via // This evaluator checks two SVals for equality. The first SVal is provided via
@@ -87,17 +89,22 @@ void EnumCastOutOfRangeChecker::reportWarning(CheckerContext &C,
EnumValueCastOutOfRange.reset( EnumValueCastOutOfRange.reset(
new BugType(this, "Enum cast out of range")); new BugType(this, "Enum cast out of range"));
- llvm::SmallString<128> Msg{"The value provided to the cast expression is "+ std::string ValueStr = "", NameStr = "the enum";
- "not in the valid range of values for "};+
- StringRef EnumName{E->getName()};+ // Try to add details to the message:
- if (EnumName.empty()) {+ const auto ConcreteValue =
- Msg += "the enum";+ C.getSVal(CE->getSubExpr()).getAs<nonloc::ConcreteInt>();
- } else {+ if (ConcreteValue) {
- Msg += '\'';+ ValueStr = formatv(" '{0}'", ConcreteValue->getValue());
- Msg += EnumName;+ }
- Msg += '\'';+ if (StringRef EnumName{E->getName()}; !EnumName.empty()) {
+ NameStr = formatv("'{0}'", EnumName);
} }
+ std::string Msg = formatv("The value{0} provided to the cast expression is "
+ "not in the valid range of values for {1}",
+ ValueStr, NameStr);
+
auto BR = std::make_unique<PathSensitiveBugReport>(*EnumValueCastOutOfRange, auto BR = std::make_unique<PathSensitiveBugReport>(*EnumValueCastOutOfRange,
Msg, N); Msg, N);
bugreporter::trackExpressionValue(N, CE->getSubExpr(), *BR); bugreporter::trackExpressionValue(N, CE->getSubExpr(), *BR);
clang/test/AST/HLSL/RWBuffer-AST.hlsl
@@ -13,8 +13,6 @@
// EMPTY: ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit RWBuffer // EMPTY: ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit RWBuffer
// EMPTY-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> class depth 0 index 0 element_type // EMPTY-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> class depth 0 index 0 element_type
-// EMPTY-NEXT: TemplateArgument type 'float'
-// EMPTY-NEXT: BuiltinType 0x{{[0-9A-Fa-f]+}} 'float'
// EMPTY-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit <undeserialized declarations> class RWBuffer // EMPTY-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit <undeserialized declarations> class RWBuffer
// EMPTY-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final // EMPTY-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final
@@ -33,8 +31,6 @@ RWBuffer<float> Buffer;
// CHECK: ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit RWBuffer // CHECK: ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit RWBuffer
// CHECK-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> class depth 0 index 0 element_type // CHECK-NEXT: TemplateTypeParmDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> class depth 0 index 0 element_type
-// CHECK-NEXT: TemplateArgument type 'float'
-// CHECK-NEXT: BuiltinType 0x{{[0-9A-Fa-f]+}} 'float'
// CHECK-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit class RWBuffer definition // CHECK-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit class RWBuffer definition
// CHECK: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final // CHECK: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final
clang/test/AST/HLSL/pch.hlsl
@@ -6,7 +6,7 @@
// Make sure PCH works by using function declared in PCH header and declare a RWBuffer in current file. // Make sure PCH works by using function declared in PCH header and declare a RWBuffer in current file.
// CHECK:FunctionDecl 0x[[FOO:[0-9a-f]+]] <{{.*}}:2:1, line:4:1> line:2:8 imported used foo 'float2 (float2, float2)' // CHECK:FunctionDecl 0x[[FOO:[0-9a-f]+]] <{{.*}}:2:1, line:4:1> line:2:8 imported used foo 'float2 (float2, float2)'
-// CHECK:VarDecl 0x{{[0-9a-f]+}} <{{.*}}:10:1, col:23> col:23 Buffer 'hlsl::RWBuffer<float>':'hlsl::RWBuffer<>'+// CHECK:VarDecl 0x{{[0-9a-f]+}} <{{.*}}:10:1, col:23> col:23 Buffer 'hlsl::RWBuffer<float>'
hlsl::RWBuffer<float> Buffer; hlsl::RWBuffer<float> Buffer;
float2 bar(float2 a, float2 b) { float2 bar(float2 a, float2 b) {
clang/test/AST/HLSL/pch_with_buf.hlsl
@@ -5,9 +5,9 @@
// Make sure PCH works by using function declared in PCH header. // Make sure PCH works by using function declared in PCH header.
// CHECK:FunctionDecl 0x[[FOO:[0-9a-f]+]] <{{.*}}:2:1, line:4:1> line:2:8 imported used foo 'float2 (float2, float2)' // CHECK:FunctionDecl 0x[[FOO:[0-9a-f]+]] <{{.*}}:2:1, line:4:1> line:2:8 imported used foo 'float2 (float2, float2)'
// Make sure buffer defined in PCH works. // Make sure buffer defined in PCH works.
-// CHECK:VarDecl 0x{{[0-9a-f]+}} <line:6:1, col:17> col:17 imported Buf 'RWBuffer<float>':'hlsl::RWBuffer<>'+// CHECK:VarDecl 0x{{[0-9a-f]+}} <line:6:1, col:17> col:17 imported Buf 'RWBuffer<float>'
// Make sure declare a RWBuffer in current file works. // Make sure declare a RWBuffer in current file works.
-// CHECK:VarDecl 0x{{[0-9a-f]+}} <{{.*}}:11:1, col:23> col:23 Buf2 'hlsl::RWBuffer<float>':'hlsl::RWBuffer<>'+// CHECK:VarDecl 0x{{[0-9a-f]+}} <{{.*}}:11:1, col:23> col:23 Buf2 'hlsl::RWBuffer<float>'
hlsl::RWBuffer<float> Buf2; hlsl::RWBuffer<float> Buf2;
float2 bar(float2 a, float2 b) { float2 bar(float2 a, float2 b) {
clang/test/AST/HLSL/resource_binding_attr.hlsl
@@ -23,15 +23,15 @@ float foo() {
return a + b; return a + b;
} }
-// CHECK: VarDecl 0x{{[0-9a-f]+}} <{{.*}}> col:17 UAV 'RWBuffer<float>':'hlsl::RWBuffer<>' callinit+// CHECK: VarDecl 0x{{[0-9a-f]+}} <{{.*}}> col:17 UAV 'RWBuffer<float>':'hlsl::RWBuffer<float>' callinit
-// CHECK-NEXT:-CXXConstructExpr 0x{{[0-9a-f]+}} <col:17> 'RWBuffer<float>':'hlsl::RWBuffer<>' 'void ()'+// CHECK-NEXT:-CXXConstructExpr 0x{{[0-9a-f]+}} <col:17> 'RWBuffer<float>':'hlsl::RWBuffer<float>' 'void ()'
// CHECK-NEXT:-HLSLResourceBindingAttr 0x{{[0-9a-f]+}} <col:23> "u3" "space0" // CHECK-NEXT:-HLSLResourceBindingAttr 0x{{[0-9a-f]+}} <col:23> "u3" "space0"
RWBuffer<float> UAV : register(u3); RWBuffer<float> UAV : register(u3);
-// CHECK: -VarDecl 0x{{[0-9a-f]+}} <{{.*}}> col:17 UAV1 'RWBuffer<float>':'hlsl::RWBuffer<>' callinit+// CHECK: -VarDecl 0x{{[0-9a-f]+}} <{{.*}}> col:17 UAV1 'RWBuffer<float>':'hlsl::RWBuffer<float>' callinit
-// CHECK-NEXT:-CXXConstructExpr 0x{{[0-9a-f]+}} <col:17> 'RWBuffer<float>':'hlsl::RWBuffer<>' 'void ()'+// CHECK-NEXT:-CXXConstructExpr 0x{{[0-9a-f]+}} <col:17> 'RWBuffer<float>':'hlsl::RWBuffer<float>' 'void ()'
// CHECK-NEXT:-HLSLResourceBindingAttr 0x{{[0-9a-f]+}} <col:24> "u2" "space0" // CHECK-NEXT:-HLSLResourceBindingAttr 0x{{[0-9a-f]+}} <col:24> "u2" "space0"
-// CHECK-NEXT:-VarDecl 0x{{[0-9a-f]+}} <col:1, col:38> col:38 UAV2 'RWBuffer<float>':'hlsl::RWBuffer<>' callinit+// CHECK-NEXT:-VarDecl 0x{{[0-9a-f]+}} <col:1, col:38> col:38 UAV2 'RWBuffer<float>':'hlsl::RWBuffer<float>' callinit
-// CHECK-NEXT:-CXXConstructExpr 0x{{[0-9a-f]+}} <col:38> 'RWBuffer<float>':'hlsl::RWBuffer<>' 'void ()'+// CHECK-NEXT:-CXXConstructExpr 0x{{[0-9a-f]+}} <col:38> 'RWBuffer<float>':'hlsl::RWBuffer<float>' 'void ()'
// CHECK-NEXT:-HLSLResourceBindingAttr 0x{{[0-9a-f]+}} <col:45> "u4" "space0" // CHECK-NEXT:-HLSLResourceBindingAttr 0x{{[0-9a-f]+}} <col:45> "u4" "space0"
RWBuffer<float> UAV1 : register(u2), UAV2 : register(u4); RWBuffer<float> UAV1 : register(u2), UAV2 : register(u4);
clang/test/AST/Interp/builtin-functions.cpp
@@ -331,3 +331,11 @@ namespace bitreverse {
char bitreverse3[__builtin_bitreverse32(0x12345678) == 0x1E6A2C48 ? 1 : -1]; char bitreverse3[__builtin_bitreverse32(0x12345678) == 0x1E6A2C48 ? 1 : -1];
char bitreverse4[__builtin_bitreverse64(0x0123456789ABCDEFULL) == 0xF7B3D591E6A2C480 ? 1 : -1]; char bitreverse4[__builtin_bitreverse64(0x0123456789ABCDEFULL) == 0xF7B3D591E6A2C480 ? 1 : -1];
} }
+
+namespace expect {
+ constexpr int a() {
+ return 12;
+ }
+ static_assert(__builtin_expect(a(),1) == 12, "");
+ static_assert(__builtin_expect_with_probability(a(), 1, 1.0) == 12, "");
+}
clang/test/Analysis/enum-cast-out-of-range.cpp
@@ -43,115 +43,115 @@ struct S {
}; };
void unscopedUnspecified() { void unscopedUnspecified() {
- unscoped_unspecified_t InvalidBeforeRangeBegin = static_cast<unscoped_unspecified_t>(-5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}+ unscoped_unspecified_t InvalidBeforeRangeBegin = static_cast<unscoped_unspecified_t>(-5); // expected-warning {{The value '-5' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
unscoped_unspecified_t ValidNegativeValue1 = static_cast<unscoped_unspecified_t>(-4); // OK. unscoped_unspecified_t ValidNegativeValue1 = static_cast<unscoped_unspecified_t>(-4); // OK.
unscoped_unspecified_t ValidNegativeValue2 = static_cast<unscoped_unspecified_t>(-3); // OK. unscoped_unspecified_t ValidNegativeValue2 = static_cast<unscoped_unspecified_t>(-3); // OK.
- unscoped_unspecified_t InvalidInsideRange1 = static_cast<unscoped_unspecified_t>(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}+ unscoped_unspecified_t InvalidInsideRange1 = static_cast<unscoped_unspecified_t>(-2); // expected-warning {{The value '-2' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
- unscoped_unspecified_t InvalidInsideRange2 = static_cast<unscoped_unspecified_t>(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}+ unscoped_unspecified_t InvalidInsideRange2 = static_cast<unscoped_unspecified_t>(-1); // expected-warning {{The value '-1' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
- unscoped_unspecified_t InvalidInsideRange3 = static_cast<unscoped_unspecified_t>(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}+ unscoped_unspecified_t InvalidInsideRange3 = static_cast<unscoped_unspecified_t>(0); // expected-warning {{The value '0' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
unscoped_unspecified_t ValidPositiveValue1 = static_cast<unscoped_unspecified_t>(1); // OK. unscoped_unspecified_t ValidPositiveValue1 = static_cast<unscoped_unspecified_t>(1); // OK.
unscoped_unspecified_t ValidPositiveValue2 = static_cast<unscoped_unspecified_t>(2); // OK. unscoped_unspecified_t ValidPositiveValue2 = static_cast<unscoped_unspecified_t>(2); // OK.
- unscoped_unspecified_t InvalidInsideRange4 = static_cast<unscoped_unspecified_t>(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}+ unscoped_unspecified_t InvalidInsideRange4 = static_cast<unscoped_unspecified_t>(3); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
unscoped_unspecified_t ValidPositiveValue3 = static_cast<unscoped_unspecified_t>(4); // OK. unscoped_unspecified_t ValidPositiveValue3 = static_cast<unscoped_unspecified_t>(4); // OK.
- unscoped_unspecified_t InvalidAfterRangeEnd = static_cast<unscoped_unspecified_t>(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}+ unscoped_unspecified_t InvalidAfterRangeEnd = static_cast<unscoped_unspecified_t>(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
} }
void unscopedSpecified() { void unscopedSpecified() {
- unscoped_specified_t InvalidBeforeRangeBegin = static_cast<unscoped_specified_t>(-5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}+ unscoped_specified_t InvalidBeforeRangeBegin = static_cast<unscoped_specified_t>(-5); // expected-warning {{The value '-5' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}
unscoped_specified_t ValidNegativeValue1 = static_cast<unscoped_specified_t>(-4); // OK. unscoped_specified_t ValidNegativeValue1 = static_cast<unscoped_specified_t>(-4); // OK.
unscoped_specified_t ValidNegativeValue2 = static_cast<unscoped_specified_t>(-3); // OK. unscoped_specified_t ValidNegativeValue2 = static_cast<unscoped_specified_t>(-3); // OK.
- unscoped_specified_t InvalidInsideRange1 = static_cast<unscoped_specified_t>(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}+ unscoped_specified_t InvalidInsideRange1 = static_cast<unscoped_specified_t>(-2); // expected-warning {{The value '-2' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}
- unscoped_specified_t InvalidInsideRange2 = static_cast<unscoped_specified_t>(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}+ unscoped_specified_t InvalidInsideRange2 = static_cast<unscoped_specified_t>(-1); // expected-warning {{The value '-1' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}
- unscoped_specified_t InvalidInsideRange3 = static_cast<unscoped_specified_t>(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}+ unscoped_specified_t InvalidInsideRange3 = static_cast<unscoped_specified_t>(0); // expected-warning {{The value '0' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}
unscoped_specified_t ValidPositiveValue1 = static_cast<unscoped_specified_t>(1); // OK. unscoped_specified_t ValidPositiveValue1 = static_cast<unscoped_specified_t>(1); // OK.
unscoped_specified_t ValidPositiveValue2 = static_cast<unscoped_specified_t>(2); // OK. unscoped_specified_t ValidPositiveValue2 = static_cast<unscoped_specified_t>(2); // OK.
- unscoped_specified_t InvalidInsideRange4 = static_cast<unscoped_specified_t>(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}+ unscoped_specified_t InvalidInsideRange4 = static_cast<unscoped_specified_t>(3); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}
unscoped_specified_t ValidPositiveValue3 = static_cast<unscoped_specified_t>(4); // OK. unscoped_specified_t ValidPositiveValue3 = static_cast<unscoped_specified_t>(4); // OK.
- unscoped_specified_t InvalidAfterRangeEnd = static_cast<unscoped_specified_t>(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}+ unscoped_specified_t InvalidAfterRangeEnd = static_cast<unscoped_specified_t>(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}
} }
void scopedUnspecified() { void scopedUnspecified() {
- scoped_unspecified_t InvalidBeforeRangeBegin = static_cast<scoped_unspecified_t>(-5); // expected-warning{{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}+ scoped_unspecified_t InvalidBeforeRangeBegin = static_cast<scoped_unspecified_t>(-5); // expected-warning{{The value '-5' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}
scoped_unspecified_t ValidNegativeValue1 = static_cast<scoped_unspecified_t>(-4); // OK. scoped_unspecified_t ValidNegativeValue1 = static_cast<scoped_unspecified_t>(-4); // OK.
scoped_unspecified_t ValidNegativeValue2 = static_cast<scoped_unspecified_t>(-3); // OK. scoped_unspecified_t ValidNegativeValue2 = static_cast<scoped_unspecified_t>(-3); // OK.
- scoped_unspecified_t InvalidInsideRange1 = static_cast<scoped_unspecified_t>(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}+ scoped_unspecified_t InvalidInsideRange1 = static_cast<scoped_unspecified_t>(-2); // expected-warning {{The value '-2' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}
- scoped_unspecified_t InvalidInsideRange2 = static_cast<scoped_unspecified_t>(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}+ scoped_unspecified_t InvalidInsideRange2 = static_cast<scoped_unspecified_t>(-1); // expected-warning {{The value '-1' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}
- scoped_unspecified_t InvalidInsideRange3 = static_cast<scoped_unspecified_t>(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}+ scoped_unspecified_t InvalidInsideRange3 = static_cast<scoped_unspecified_t>(0); // expected-warning {{The value '0' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}
scoped_unspecified_t ValidPositiveValue1 = static_cast<scoped_unspecified_t>(1); // OK. scoped_unspecified_t ValidPositiveValue1 = static_cast<scoped_unspecified_t>(1); // OK.
scoped_unspecified_t ValidPositiveValue2 = static_cast<scoped_unspecified_t>(2); // OK. scoped_unspecified_t ValidPositiveValue2 = static_cast<scoped_unspecified_t>(2); // OK.
- scoped_unspecified_t InvalidInsideRange4 = static_cast<scoped_unspecified_t>(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}+ scoped_unspecified_t InvalidInsideRange4 = static_cast<scoped_unspecified_t>(3); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}
scoped_unspecified_t ValidPositiveValue3 = static_cast<scoped_unspecified_t>(4); // OK. scoped_unspecified_t ValidPositiveValue3 = static_cast<scoped_unspecified_t>(4); // OK.
- scoped_unspecified_t InvalidAfterRangeEnd = static_cast<scoped_unspecified_t>(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}+ scoped_unspecified_t InvalidAfterRangeEnd = static_cast<scoped_unspecified_t>(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}
} }
void scopedSpecified() { void scopedSpecified() {
- scoped_specified_t InvalidBeforeRangeBegin = static_cast<scoped_specified_t>(-5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}+ scoped_specified_t InvalidBeforeRangeBegin = static_cast<scoped_specified_t>(-5); // expected-warning {{The value '-5' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
scoped_specified_t ValidNegativeValue1 = static_cast<scoped_specified_t>(-4); // OK. scoped_specified_t ValidNegativeValue1 = static_cast<scoped_specified_t>(-4); // OK.
scoped_specified_t ValidNegativeValue2 = static_cast<scoped_specified_t>(-3); // OK. scoped_specified_t ValidNegativeValue2 = static_cast<scoped_specified_t>(-3); // OK.
- scoped_specified_t InvalidInsideRange1 = static_cast<scoped_specified_t>(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}+ scoped_specified_t InvalidInsideRange1 = static_cast<scoped_specified_t>(-2); // expected-warning {{The value '-2' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
- scoped_specified_t InvalidInsideRange2 = static_cast<scoped_specified_t>(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}+ scoped_specified_t InvalidInsideRange2 = static_cast<scoped_specified_t>(-1); // expected-warning {{The value '-1' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
- scoped_specified_t InvalidInsideRange3 = static_cast<scoped_specified_t>(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}+ scoped_specified_t InvalidInsideRange3 = static_cast<scoped_specified_t>(0); // expected-warning {{The value '0' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
scoped_specified_t ValidPositiveValue1 = static_cast<scoped_specified_t>(1); // OK. scoped_specified_t ValidPositiveValue1 = static_cast<scoped_specified_t>(1); // OK.
scoped_specified_t ValidPositiveValue2 = static_cast<scoped_specified_t>(2); // OK. scoped_specified_t ValidPositiveValue2 = static_cast<scoped_specified_t>(2); // OK.
- scoped_specified_t InvalidInsideRange4 = static_cast<scoped_specified_t>(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}+ scoped_specified_t InvalidInsideRange4 = static_cast<scoped_specified_t>(3); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
scoped_specified_t ValidPositiveValue3 = static_cast<scoped_specified_t>(4); // OK. scoped_specified_t ValidPositiveValue3 = static_cast<scoped_specified_t>(4); // OK.
- scoped_specified_t InvalidAfterRangeEnd = static_cast<scoped_specified_t>(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}+ scoped_specified_t InvalidAfterRangeEnd = static_cast<scoped_specified_t>(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
} }
void unscopedUnspecifiedCStyle() { void unscopedUnspecifiedCStyle() {
- unscoped_unspecified_t InvalidBeforeRangeBegin = (unscoped_unspecified_t)(-5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}+ unscoped_unspecified_t InvalidBeforeRangeBegin = (unscoped_unspecified_t)(-5); // expected-warning {{The value '-5' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
unscoped_unspecified_t ValidNegativeValue1 = (unscoped_unspecified_t)(-4); // OK. unscoped_unspecified_t ValidNegativeValue1 = (unscoped_unspecified_t)(-4); // OK.
unscoped_unspecified_t ValidNegativeValue2 = (unscoped_unspecified_t)(-3); // OK. unscoped_unspecified_t ValidNegativeValue2 = (unscoped_unspecified_t)(-3); // OK.
- unscoped_unspecified_t InvalidInsideRange1 = (unscoped_unspecified_t)(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}+ unscoped_unspecified_t InvalidInsideRange1 = (unscoped_unspecified_t)(-2); // expected-warning {{The value '-2' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
- unscoped_unspecified_t InvalidInsideRange2 = (unscoped_unspecified_t)(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}+ unscoped_unspecified_t InvalidInsideRange2 = (unscoped_unspecified_t)(-1); // expected-warning {{The value '-1' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
- unscoped_unspecified_t InvalidInsideRange3 = (unscoped_unspecified_t)(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}+ unscoped_unspecified_t InvalidInsideRange3 = (unscoped_unspecified_t)(0); // expected-warning {{The value '0' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
unscoped_unspecified_t ValidPositiveValue1 = (unscoped_unspecified_t)(1); // OK. unscoped_unspecified_t ValidPositiveValue1 = (unscoped_unspecified_t)(1); // OK.
unscoped_unspecified_t ValidPositiveValue2 = (unscoped_unspecified_t)(2); // OK. unscoped_unspecified_t ValidPositiveValue2 = (unscoped_unspecified_t)(2); // OK.
- unscoped_unspecified_t InvalidInsideRange4 = (unscoped_unspecified_t)(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}+ unscoped_unspecified_t InvalidInsideRange4 = (unscoped_unspecified_t)(3); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
unscoped_unspecified_t ValidPositiveValue3 = (unscoped_unspecified_t)(4); // OK. unscoped_unspecified_t ValidPositiveValue3 = (unscoped_unspecified_t)(4); // OK.
- unscoped_unspecified_t InvalidAfterRangeEnd = (unscoped_unspecified_t)(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}+ unscoped_unspecified_t InvalidAfterRangeEnd = (unscoped_unspecified_t)(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
} }
void unscopedSpecifiedCStyle() { void unscopedSpecifiedCStyle() {
- unscoped_specified_t InvalidBeforeRangeBegin = (unscoped_specified_t)(-5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}+ unscoped_specified_t InvalidBeforeRangeBegin = (unscoped_specified_t)(-5); // expected-warning {{The value '-5' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}
unscoped_specified_t ValidNegativeValue1 = (unscoped_specified_t)(-4); // OK. unscoped_specified_t ValidNegativeValue1 = (unscoped_specified_t)(-4); // OK.
unscoped_specified_t ValidNegativeValue2 = (unscoped_specified_t)(-3); // OK. unscoped_specified_t ValidNegativeValue2 = (unscoped_specified_t)(-3); // OK.
- unscoped_specified_t InvalidInsideRange1 = (unscoped_specified_t)(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}+ unscoped_specified_t InvalidInsideRange1 = (unscoped_specified_t)(-2); // expected-warning {{The value '-2' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}
- unscoped_specified_t InvalidInsideRange2 = (unscoped_specified_t)(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}+ unscoped_specified_t InvalidInsideRange2 = (unscoped_specified_t)(-1); // expected-warning {{The value '-1' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}
- unscoped_specified_t InvalidInsideRange3 = (unscoped_specified_t)(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}+ unscoped_specified_t InvalidInsideRange3 = (unscoped_specified_t)(0); // expected-warning {{The value '0' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}
unscoped_specified_t ValidPositiveValue1 = (unscoped_specified_t)(1); // OK. unscoped_specified_t ValidPositiveValue1 = (unscoped_specified_t)(1); // OK.
unscoped_specified_t ValidPositiveValue2 = (unscoped_specified_t)(2); // OK. unscoped_specified_t ValidPositiveValue2 = (unscoped_specified_t)(2); // OK.
- unscoped_specified_t InvalidInsideRange4 = (unscoped_specified_t)(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}+ unscoped_specified_t InvalidInsideRange4 = (unscoped_specified_t)(3); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}
unscoped_specified_t ValidPositiveValue3 = (unscoped_specified_t)(4); // OK. unscoped_specified_t ValidPositiveValue3 = (unscoped_specified_t)(4); // OK.
- unscoped_specified_t InvalidAfterRangeEnd = (unscoped_specified_t)(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}+ unscoped_specified_t InvalidAfterRangeEnd = (unscoped_specified_t)(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'unscoped_specified_t'}}
} }
void scopedUnspecifiedCStyle() { void scopedUnspecifiedCStyle() {
- scoped_unspecified_t InvalidBeforeRangeBegin = (scoped_unspecified_t)(-5); // expected-warning{{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}+ scoped_unspecified_t InvalidBeforeRangeBegin = (scoped_unspecified_t)(-5); // expected-warning{{The value '-5' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}
scoped_unspecified_t ValidNegativeValue1 = (scoped_unspecified_t)(-4); // OK. scoped_unspecified_t ValidNegativeValue1 = (scoped_unspecified_t)(-4); // OK.
scoped_unspecified_t ValidNegativeValue2 = (scoped_unspecified_t)(-3); // OK. scoped_unspecified_t ValidNegativeValue2 = (scoped_unspecified_t)(-3); // OK.
- scoped_unspecified_t InvalidInsideRange1 = (scoped_unspecified_t)(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}+ scoped_unspecified_t InvalidInsideRange1 = (scoped_unspecified_t)(-2); // expected-warning {{The value '-2' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}
- scoped_unspecified_t InvalidInsideRange2 = (scoped_unspecified_t)(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}+ scoped_unspecified_t InvalidInsideRange2 = (scoped_unspecified_t)(-1); // expected-warning {{The value '-1' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}
- scoped_unspecified_t InvalidInsideRange3 = (scoped_unspecified_t)(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}+ scoped_unspecified_t InvalidInsideRange3 = (scoped_unspecified_t)(0); // expected-warning {{The value '0' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}
scoped_unspecified_t ValidPositiveValue1 = (scoped_unspecified_t)(1); // OK. scoped_unspecified_t ValidPositiveValue1 = (scoped_unspecified_t)(1); // OK.
scoped_unspecified_t ValidPositiveValue2 = (scoped_unspecified_t)(2); // OK. scoped_unspecified_t ValidPositiveValue2 = (scoped_unspecified_t)(2); // OK.
- scoped_unspecified_t InvalidInsideRange4 = (scoped_unspecified_t)(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}+ scoped_unspecified_t InvalidInsideRange4 = (scoped_unspecified_t)(3); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}
scoped_unspecified_t ValidPositiveValue3 = (scoped_unspecified_t)(4); // OK. scoped_unspecified_t ValidPositiveValue3 = (scoped_unspecified_t)(4); // OK.
- scoped_unspecified_t InvalidAfterRangeEnd = (scoped_unspecified_t)(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}+ scoped_unspecified_t InvalidAfterRangeEnd = (scoped_unspecified_t)(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'scoped_unspecified_t'}}
} }
void scopedSpecifiedCStyle() { void scopedSpecifiedCStyle() {
- scoped_specified_t InvalidBeforeRangeBegin = (scoped_specified_t)(-5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}+ scoped_specified_t InvalidBeforeRangeBegin = (scoped_specified_t)(-5); // expected-warning {{The value '-5' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
scoped_specified_t ValidNegativeValue1 = (scoped_specified_t)(-4); // OK. scoped_specified_t ValidNegativeValue1 = (scoped_specified_t)(-4); // OK.
scoped_specified_t ValidNegativeValue2 = (scoped_specified_t)(-3); // OK. scoped_specified_t ValidNegativeValue2 = (scoped_specified_t)(-3); // OK.
- scoped_specified_t InvalidInsideRange1 = (scoped_specified_t)(-2); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}+ scoped_specified_t InvalidInsideRange1 = (scoped_specified_t)(-2); // expected-warning {{The value '-2' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
- scoped_specified_t InvalidInsideRange2 = (scoped_specified_t)(-1); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}+ scoped_specified_t InvalidInsideRange2 = (scoped_specified_t)(-1); // expected-warning {{The value '-1' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
- scoped_specified_t InvalidInsideRange3 = (scoped_specified_t)(0); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}+ scoped_specified_t InvalidInsideRange3 = (scoped_specified_t)(0); // expected-warning {{The value '0' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
scoped_specified_t ValidPositiveValue1 = (scoped_specified_t)(1); // OK. scoped_specified_t ValidPositiveValue1 = (scoped_specified_t)(1); // OK.
scoped_specified_t ValidPositiveValue2 = (scoped_specified_t)(2); // OK. scoped_specified_t ValidPositiveValue2 = (scoped_specified_t)(2); // OK.
- scoped_specified_t InvalidInsideRange4 = (scoped_specified_t)(3); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}+ scoped_specified_t InvalidInsideRange4 = (scoped_specified_t)(3); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
scoped_specified_t ValidPositiveValue3 = (scoped_specified_t)(4); // OK. scoped_specified_t ValidPositiveValue3 = (scoped_specified_t)(4); // OK.
- scoped_specified_t InvalidAfterRangeEnd = (scoped_specified_t)(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}+ scoped_specified_t InvalidAfterRangeEnd = (scoped_specified_t)(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
} }
unscoped_unspecified_t unused; unscoped_unspecified_t unused;
@@ -194,13 +194,13 @@ void rangeConstrained6(int input) {
void rangeConstrained7(int input) { void rangeConstrained7(int input) {
if (input >= 3 && input <= 3) if (input >= 3 && input <= 3)
- auto value = static_cast<scoped_specified_t>(input); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}+ auto value = static_cast<scoped_specified_t>(input); // expected-warning {{The value '3' provided to the cast expression is not in the valid range of values for 'scoped_specified_t'}}
} }
void enumBitFieldAssignment() { void enumBitFieldAssignment() {
S s; S s;
s.E = static_cast<unscoped_unspecified_t>(4); // OK. s.E = static_cast<unscoped_unspecified_t>(4); // OK.
- s.E = static_cast<unscoped_unspecified_t>(5); // expected-warning {{The value provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}+ s.E = static_cast<unscoped_unspecified_t>(5); // expected-warning {{The value '5' provided to the cast expression is not in the valid range of values for 'unscoped_unspecified_t'}}
} }
clang/test/C/C2x/n2836_n2939.c
@@ -0,0 +1,83 @@
+// RUN: %clang_cc1 -x c -std=c2x -fsyntax-only -verify %s
+// RUN: %clang_cc1 -x c -std=c2x -E -DPP_ONLY=1 %s | FileCheck %s --strict-whitespace
+
+/* WG14 N2836: Clang 15
+ * Identifier Syntax using Unicode Standard Annex 31
+ */
+
+/* WG14 N2939: Clang 15
+ * Identifier Syntax Fixes
+ */
+
+// Some of the tests below are derived from clang/test/Lexer/unicode.c.
+
+// This file contains Unicode characters; please do not "fix" them!
+
+// No diagnostics for pragma directives.
+#pragma mark ¡Unicode!
+
+// lone non-identifier characters are allowed in preprocessing.
+#define COPYRIGHT Copyright © 2012
+#define XSTR(X) #X
+#define STR(X) XSTR(X)
+
+static const char *copyright = STR(COPYRIGHT); // no-warning
+// CHECK: static const char *copyright = "Copyright © {{2012}}";
+
+#if PP_ONLY
+COPYRIGHT
+// CHECK: Copyright © {{2012}}
+#endif
+
+// The characters in the following identifiers are no longer valid as either
+// start or continuation characters as of C23. These are taken from section 1
+// of N2836.
+extern int \N{CONSTRUCTION WORKER}; // expected-error {{expected identifier or '('}}
+extern int X\N{CONSTRUCTION WORKER}; // expected-error {{character <U+1F477> not allowed in an identifier}}
+extern int \U0001F477; // expected-error {{expected identifier or '('}}
+extern int X\U0001F477; // expected-error {{character <U+1F477> not allowed in an identifier}}
+extern int 👷; // expected-error {{unexpected character <U+1F477>}} \
+ // expected-warning {{declaration does not declare anything}}
+extern int X👷; // expected-error {{character <U+1F477> not allowed in an identifier}}
+extern int 🕐; // expected-error {{unexpected character <U+1F550>}} \
+ // expected-warning {{declaration does not declare anything}}
+extern int X🕐; // expected-error {{character <U+1F550> not allowed in an identifier}}
+extern int 💀; // expected-error {{unexpected character <U+1F480>}} \
+ // expected-warning {{declaration does not declare anything}}
+extern int X💀; // expected-error {{character <U+1F480> not allowed in an identifier}}
+extern int 👊; // expected-error {{unexpected character <U+1F44A>}} \
+ // expected-warning {{declaration does not declare anything}}
+extern int X👊; // expected-error {{character <U+1F44A> not allowed in an identifier}}
+extern int 🚀; // expected-error {{unexpected character <U+1F680>}} \
+ // expected-warning {{declaration does not declare anything}}
+extern int X🚀; // expected-error {{character <U+1F680> not allowed in an identifier}}
+extern int 😀; // expected-error {{unexpected character <U+1F600>}} \
+ // expected-warning {{declaration does not declare anything}}
+extern int X😀; // expected-error {{character <U+1F600> not allowed in an identifier}}
+
+// The characters in the following identifiers are not allowed as start
+// characters, but are allowed as continuation characters.
+extern int \N{ARABIC-INDIC DIGIT ZERO}; // expected-error {{expected identifier or '('}}
+extern int X\N{ARABIC-INDIC DIGIT ZERO};
+extern int \u0661; // expected-error {{expected identifier or '('}}
+extern int X\u0661;
+extern int ٢; // expected-error {{character <U+0662> not allowed at the start of an identifier}} \\
+ // expected-warning {{declaration does not declare anything}}
+extern int X٠;
+
+// The characters in the following identifiers are not valid start or
+// continuation characters in the standard, but are accepted as a conforming
+// extension.
+extern int \N{SUPERSCRIPT ZERO}; // expected-error {{expected identifier or '('}}
+extern int X\N{SUPERSCRIPT ZERO}; // expected-warning {{mathematical notation character <U+2070> in an identifier is a Clang extension}}
+extern int \u00B9; // expected-error {{expected identifier or '('}}
+extern int X\u00B9; // expected-warning {{mathematical notation character <U+00B9> in an identifier is a Clang extension}}
+extern int ²; // expected-error {{character <U+00B2> not allowed at the start of an identifier}} \\
+ // expected-warning {{declaration does not declare anything}}
+extern int X²; // expected-warning {{mathematical notation character <U+00B2> in an identifier is a Clang extension}}
+extern int \N{PARTIAL DIFFERENTIAL}; // expected-warning {{mathematical notation character <U+2202> in an identifier is a Clang extension}}
+extern int X\N{PARTIAL DIFFERENTIAL}; // expected-warning {{mathematical notation character <U+2202> in an identifier is a Clang extension}}
+extern int \u2207; // expected-warning {{mathematical notation character <U+2207> in an identifier is a Clang extension}}
+extern int X\u2207; // expected-warning {{mathematical notation character <U+2207> in an identifier is a Clang extension}}
+extern int ∞; // expected-warning {{mathematical notation character <U+221E> in an identifier is a Clang extension}}
+extern int X∞; // expected-warning {{mathematical notation character <U+221E> in an identifier is a Clang extension}}
clang/test/CXX/drs/dr10xx.cpp
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++98 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++11 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++14 %s -verify=expected,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++20 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++23 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors
namespace std { namespace std {
__extension__ typedef __SIZE_TYPE__ size_t; __extension__ typedef __SIZE_TYPE__ size_t;
@@ -18,30 +18,40 @@ namespace dr1004 { // dr1004: 5
template<typename> struct A {}; template<typename> struct A {};
template<typename> struct B1 {}; template<typename> struct B1 {};
template<template<typename> class> struct B2 {}; template<template<typename> class> struct B2 {};
- template<typename X> void f(); // expected-note {{[with X = dr1004::A<int>]}}+ template<typename X> void f(); // #dr1004-f-1
- template<template<typename> class X> void f(); // expected-note {{[with X = dr1004::A]}}+ template<template<typename> class X> void f(); // #dr1004-f-2
- template<template<typename> class X> void g(); // expected-note {{[with X = dr1004::A]}}+ template<template<typename> class X> void g(); // #dr1004-g-1
- template<typename X> void g(); // expected-note {{[with X = dr1004::A<int>]}}+ template<typename X> void g(); // #dr1004-g-2
struct C : A<int> { struct C : A<int> {
B1<A> b1a; B1<A> b1a;
B2<A> b2a; B2<A> b2a;
void h() { void h() {
- f<A>(); // expected-error {{ambiguous}}+ f<A>();
- g<A>(); // expected-error {{ambiguous}}+ // expected-error@-1 {{call to 'f' is ambiguous}}
+ // expected-note@#dr1004-f-1 {{candidate function [with X = dr1004::A<int>]}}
+ // expected-note@#dr1004-f-2 {{candidate function [with X = dr1004::A]}}
+ g<A>();
+ // expected-error@-1 {{call to 'g' is ambiguous}}
+ // expected-note@#dr1004-g-1 {{candidate function [with X = dr1004::A]}}
+ // expected-note@#dr1004-g-2 {{candidate function [with X = dr1004::A<int>]}}
} }
}; };
// This example (from the standard) is actually ill-formed, because // This example (from the standard) is actually ill-formed, because
// name lookup of "T::template A" names the constructor. // name lookup of "T::template A" names the constructor.
- template<class T, template<class> class U = T::template A> struct Third { }; // expected-error {{is a constructor name}}+ template<class T, template<class> class U = T::template A> struct Third { };
- Third<A<int> > t; // expected-note {{in instantiation of default argument}}+ // expected-error@-1 {{is a constructor name}}
+ // expected-note@#dr1004-t {{in instantiation of default argument}}
+ Third<A<int> > t; // #dr1004-t
} }
namespace dr1042 { // dr1042: 3.5 namespace dr1042 { // dr1042: 3.5
#if __cplusplus >= 201402L #if __cplusplus >= 201402L
// C++14 added an attribute that we can test the semantics of. // C++14 added an attribute that we can test the semantics of.
- using foo [[deprecated]] = int; // expected-note {{'foo' has been explicitly marked deprecated here}}+ using foo [[deprecated]] = int; // #dr1042-using
- foo f = 12; // expected-warning {{'foo' is deprecated}}+ foo f = 12;
+ // since-cxx14-warning@-1 {{'foo' is deprecated}}
+ // since-cxx14-note@#dr1042-using {{'foo' has been explicitly marked deprecated here}}
#elif __cplusplus >= 201103L #elif __cplusplus >= 201103L
// C++11 did not have any attributes that could be applied to an alias // C++11 did not have any attributes that could be applied to an alias
// declaration, so the best we can test is that we accept an empty attribute // declaration, so the best we can test is that we accept an empty attribute
@@ -76,7 +86,8 @@ namespace dr1054 { // dr1054: no
// which copy-initializes a temporary from 'a'. Therefore this is // which copy-initializes a temporary from 'a'. Therefore this is
// ill-formed because A does not have a volatile copy constructor. // ill-formed because A does not have a volatile copy constructor.
// (We might want to track this aspect under dr1383 instead?) // (We might want to track this aspect under dr1383 instead?)
- a; // expected-warning {{assign into a variable to force a volatile load}}+ a;
+ // expected-warning@-1 {{expression result unused; assign into a variable to force a volatile load}}
} }
} }
clang/test/CXX/drs/dr11xx.cpp
@@ -1,30 +1,30 @@
-// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++98 %s -verify=expected,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++11 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++14 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++17 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++2a %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++2a %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
-namespace dr1111 { // dr1111: yes+namespace dr1111 { // dr1111: 3.2
namespace example1 { namespace example1 {
-template <typename> struct set;+template <typename> struct set; // #dr1111-struct-set
struct X { struct X {
- template <typename T> void set(const T &value);+ template <typename T> void set(const T &value); // #dr1111-func-set
}; };
void foo() { void foo() {
X x; X x;
-#pragma clang diagnostic push+ // FIXME: should we backport C++11 behavior?
-#if __cplusplus < 201103L
-#pragma clang diagnostic ignored "-Wambiguous-member-template"
-#endif
x.set<double>(3.2); x.set<double>(3.2);
-#pragma clang diagnostic pop+ // cxx98-error@-1 {{lookup of 'set' in member access expression is ambiguous; using member of 'X'}}
+ // cxx98-note@#dr1111-func-set {{lookup in the object type 'X' refers here}}
+ // cxx98-note@#dr1111-struct-set {{lookup from the current scope refers here}}
} }
struct Y {}; struct Y {};
void bar() { void bar() {
Y y; Y y;
- y.set<double>(3.2); // expected-error {{no member named 'set' in 'dr1111::example1::Y'}}+ y.set<double>(3.2);
+ // expected-error@-1 {{no member named 'set' in 'dr1111::example1::Y'}}
} }
} // namespace example1 } // namespace example1
@@ -46,8 +46,10 @@ void baz() {
namespace dr1113 { // dr1113: partial namespace dr1113 { // dr1113: partial
namespace named { namespace named {
- extern int a; // expected-note {{previous}}+ extern int a; // #dr1113-a
- static int a; // expected-error {{static declaration of 'a' follows non-static}}+ static int a;
+ // expected-error@-1 {{static declaration of 'a' follows non-static}}
+ // expected-note@#dr1113-a {{previous declaration is here}}
} }
namespace { namespace {
extern int a; extern int a;
clang/test/CXX/drs/dr12xx.cpp
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++98 %s -verify=expected,cxx98-14,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++11 %s -verify=expected,cxx98-14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++14 %s -verify=expected,cxx98-14,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx17,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++20 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx17,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++23 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx17,since-cxx14,since-cxx11,since-cxx23 -fexceptions -fcxx-exceptions -pedantic-errors
// dr1200: na // dr1200: na
@@ -40,28 +40,33 @@ struct S {
S* operator()(); S* operator()();
int N; int N;
int M; int M;
-#if __cplusplus > 202002L+#if __cplusplus >= 202302L
template <typename T> template <typename T>
static constexpr auto V = 0; static constexpr auto V = 0;
void f(char); void f(char);
void f(int); void f(int);
void mem(S s) { void mem(S s) {
- auto(s)()->M; //expected-warning {{expression result unused}}+ auto(s)()->M;
- auto(s)()->V<int>; //expected-warning {{expression result unused}}+ // since-cxx23-warning@-1 {{expression result unused}}
+ auto(s)()->V<int>;
+ // since-cxx23-warning@-1 {{expression result unused}}
auto(s)()->f(0); auto(s)()->f(0);
} }
#endif #endif
}; };
void f(S s) { void f(S s) {
{ {
-#if __cplusplus > 202002L+#if __cplusplus >= 202302L
- auto(s)()->N; //expected-warning {{expression result unused}}+ auto(s)()->N;
+ //since-cxx23-warning@-1 {{expression result unused}}
#endif #endif
auto(s)()->M; auto(s)()->M;
} }
{ {
- S(s)()->N; //expected-warning {{expression result unused}}+ S(s)()->N;
- S(s)()->M; //expected-warning {{expression result unused}}+ // since-cxx11-warning@-1 {{expression result unused}}
+ S(s)()->M;
+ // since-cxx11-warning@-1 {{expression result unused}}
} }
} }
@@ -74,23 +79,27 @@ void g() {
A a(B ()->C); A a(B ()->C);
A b(auto ()->C); A b(auto ()->C);
static_assert(sizeof(B ()->C[1] == sizeof(int)), ""); static_assert(sizeof(B ()->C[1] == sizeof(int)), "");
- sizeof(auto () -> C[1]); // expected-error{{function cannot return array type 'C[1]'}}+ sizeof(auto () -> C[1]);
+ // since-cxx11-error@-1 {{function cannot return array type 'C[1]' (aka 'dr1223::BB[1]')}}
} }
} }
#endif #endif
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
-namespace dr1227 { // dr1227: yes+namespace dr1227 { // dr1227: 3.0
-template <class T> struct A { using X = typename T::X; }; // expected-error {{type 'int' cannot be used prior to '::' because it has no members}}+template <class T> struct A { using X = typename T::X; };
+// since-cxx11-error@-1 {{type 'int' cannot be used prior to '::' because it has no members}}
+// since-cxx11-note@#dr1227-g {{in instantiation of template class 'dr1227::A<int>' requested here}}
+// since-cxx11-note@#dr1227-g-int {{while substituting explicitly-specified template arguments into function template 'g'}}
template <class T> typename T::X f(typename A<T>::X); template <class T> typename T::X f(typename A<T>::X);
template <class T> void f(...) { } template <class T> void f(...) { }
-template <class T> auto g(typename A<T>::X) -> typename T::X; // expected-note {{in instantiation of template class 'dr1227::A<int>' requested here}}+template <class T> auto g(typename A<T>::X) -> typename T::X; // #dr1227-g
template <class T> void g(...) { } template <class T> void g(...) { }
void h() { void h() {
f<int>(0); // OK, substituting return type causes deduction to fail f<int>(0); // OK, substituting return type causes deduction to fail
- g<int>(0); // expected-note {{while substituting explicitly-specified template arguments into function template 'g'}}+ g<int>(0); // #dr1227-g-int
} }
} }
#endif #endif
@@ -109,15 +118,21 @@ struct Derived : Base {
namespace dr1265 { // dr1265: 5 namespace dr1265 { // dr1265: 5
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
- auto a = 0, b() -> int; // expected-error {{declaration with trailing return type must be the only declaration in its group}}+ auto a = 0, b() -> int;
- auto b() -> int, d = 0; // expected-error {{declaration with trailing return type must be the only declaration in its group}}+ // since-cxx11-error@-1 {{declaration with trailing return type must be the only declaration in its group}}
- auto e() -> int, f() -> int; // expected-error {{declaration with trailing return type must be the only declaration in its group}}+ auto b() -> int, d = 0;
+ // since-cxx11-error@-1 {{declaration with trailing return type must be the only declaration in its group}}
+ auto e() -> int, f() -> int;
+ // since-cxx11-error@-1 {{declaration with trailing return type must be the only declaration in its group}}
#endif #endif
#if __cplusplus >= 201402L #if __cplusplus >= 201402L
- auto g(), h = 0; // expected-error {{function with deduced return type must be the only declaration in its group}}+ auto g(), h = 0;
- auto i = 0, j(); // expected-error {{function with deduced return type must be the only declaration in its group}}+ // since-cxx14-error@-1 {{function with deduced return type must be the only declaration in its group}}
- auto k(), l(); // expected-error {{function with deduced return type must be the only declaration in its group}}+ auto i = 0, j();
+ // since-cxx14-error@-1 {{function with deduced return type must be the only declaration in its group}}
+ auto k(), l();
+ // since-cxx14-error@-1 {{function with deduced return type must be the only declaration in its group}}
#endif #endif
} }
@@ -130,16 +145,16 @@ namespace dr1295 { // dr1295: 4
X x = {1}; X x = {1};
- unsigned const &r1 = static_cast<X &&>(x).bitfield; // expected-error 0-1{{C++11}}+ unsigned const &r1 = static_cast<X &&>(x).bitfield;
- unsigned const &r2 = static_cast<unsigned &&>(x.bitfield); // expected-error 0-1{{C++11}}+ // cxx98-error@-1 {{rvalue references are a C++11 extension}}
+ unsigned const &r2 = static_cast<unsigned &&>(x.bitfield);
+ // cxx98-error@-1 {{rvalue references are a C++11 extension}}
- template<unsigned &r> struct Y {};+ template<unsigned &r> struct Y {}; // #dr1295-Y
- Y<x.bitfield> y;+ Y<x.bitfield> y; // #dr1295-y
-#if __cplusplus <= 201402L+ // cxx98-14-error@-1 {{non-type template argument does not refer to any declaration}}
- // expected-error@-2 {{does not refer to any declaration}} expected-note@-3 {{here}}+ // cxx98-14-note@#dr1295-Y {{template parameter is declared here}}
-#else+ // since-cxx17-error@#dr1295-y {{non-type template argument refers to subobject 'x.bitfield'}}
- // expected-error@-4 {{refers to subobject}}
-#endif
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
const unsigned other = 0; const unsigned other = 0;
clang/test/CXX/drs/dr13xx.cpp
@@ -1,7 +1,10 @@
-// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++98 %s -verify=expected,cxx98-14,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++11 %s -verify=expected,cxx11-17,cxx11-14,cxx98-14,since-cxx11,cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++14 %s -verify=expected,cxx11-17,cxx11-14,since-cxx14,cxx98-14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++17 %s -verify=expected,cxx11-17,since-cxx14,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx14,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx14,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx14,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
__extension__ typedef __SIZE_TYPE__ size_t; __extension__ typedef __SIZE_TYPE__ size_t;
@@ -14,11 +17,13 @@ namespace std {
} }
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
-namespace dr1305 { // dr1305: yes+namespace dr1305 { // dr1305: 3.0
-struct Incomplete; // expected-note {{forward declaration of 'dr1305::Incomplete'}}+struct Incomplete; // #dr1305-Incomplete
struct Complete {}; struct Complete {};
-int incomplete = alignof(Incomplete(&)[]); // expected-error {{invalid application of 'alignof' to an incomplete type 'Incomplete'}}+int incomplete = alignof(Incomplete(&)[]);
+// since-cxx11-error@-1 {{invalid application of 'alignof' to an incomplete type 'Incomplete'}}
+// since-cxx11-note@#dr1305-Incomplete {{forward declaration of 'dr1305::Incomplete'}}
int complete = alignof(Complete(&)[]); int complete = alignof(Complete(&)[]);
} }
#endif #endif
@@ -36,9 +41,11 @@ void caller() {
} // namespace dr1307 } // namespace dr1307
namespace dr1310 { // dr1310: 5 namespace dr1310 { // dr1310: 5
- struct S {} * sp = new S::S; // expected-error {{qualified reference to 'S' is a constructor name}}+ struct S {} * sp = new S::S;
+ // expected-error@-1 {{qualified reference to 'S' is a constructor name rather than a type in this context}}
void f() { void f() {
- S::S(a); // expected-error {{qualified reference to 'S' is a constructor name}}+ S::S(a);
+ // expected-error@-1 {{qualified reference to 'S' is a constructor name rather than a type in this context}}
} }
struct T { int n; typedef int U; typedef T V; }; struct T { int n; typedef int U; typedef T V; };
int k = T().T::T::n; int k = T().T::T::n;
@@ -64,39 +71,67 @@ namespace dr1310 { // dr1310: 5
template<typename T> struct W : WBase<T> { typedef int X; int n; }; template<typename T> struct W : WBase<T> { typedef int X; int n; };
void w_test() { void w_test() {
- W<int>::W w1a; // expected-error {{qualified reference to 'W' is a constructor name}}+ W<int>::W w1a;
+ // expected-error@-1 {{qualified reference to 'W' is a constructor name rather than a type in this context}}
W<int>::W::X w1ax; W<int>::W::X w1ax;
- W<int>::W<int> w1b; // expected-error {{qualified reference to 'W' is a constructor name}}+ W<int>::W<int> w1b;
+ // expected-error@-1 {{qualified reference to 'W' is a constructor name rather than a template name in this context}}
W<int>::W<int>::X w1bx; W<int>::W<int>::X w1bx;
- typename W<int>::W w2a; // expected-error {{qualified reference to 'W' is a constructor name}} expected-error 0-1{{outside of a template}}+ typename W<int>::W w2a;
- typename W<int>::W::X w2ax; // expected-error 0-1{{outside of a template}}+ // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a type in this context, despite preceding 'typename' keyword}}
- typename W<int>::W<int> w2b; // expected-error {{qualified reference to 'W' is a constructor name}} expected-error 0-1{{outside of a template}}+ // cxx98-error@-2 {{'typename' occurs outside of a template}}
- typename W<int>::W<int>::X w2bx; // expected-error 0-1{{outside of a template}}+ typename W<int>::W::X w2ax;
- W<int>::template W<int> w3; // expected-error {{qualified reference to 'W' is a constructor name}} expected-error 0-1{{outside of a template}}+ // cxx98-error@-1 {{'typename' occurs outside of a template}}
- W<int>::template W<int>::X w3x; // expected-error 0-1{{outside of a template}}+ typename W<int>::W<int> w2b;
- typename W<int>::template W<int> w4; // expected-error {{qualified reference to 'W' is a constructor name}} expected-error 0-2{{outside of a template}}+ // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a template name in this context, despite preceding 'typename' keyword}}
- typename W<int>::template W<int>::X w4x; // expected-error 0-2{{outside of a template}}+ // cxx98-error@-2 {{'typename' occurs outside of a template}}
-+ typename W<int>::W<int>::X w2bx;
- TT<W<int>::W> tt1; // expected-error {{qualified reference to 'W' is a constructor name}}+ // cxx98-error@-1 {{'typename' occurs outside of a template}}
- TTy<W<int>::W> tt1a; // expected-error {{qualified reference to 'W' is a constructor name}}+ W<int>::template W<int> w3;
- TT<W<int>::template W> tt2; // expected-error {{qualified reference to 'W' is a constructor name}} expected-error 0-1{{outside of a template}}+ // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a template name in this context, despite preceding 'template' keyword}}
+ // cxx98-error@-2 {{'template' keyword outside of a template}}
+ W<int>::template W<int>::X w3x;
+ // cxx98-error@-1 {{'template' keyword outside of a template}}
+ typename W<int>::template W<int> w4;
+ // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a template name in this context, despite preceding 'template' keyword}}
+ // cxx98-error@-2 {{'template' keyword outside of a template}}
+ // cxx98-error@-3 {{'typename' occurs outside of a template}}
+ typename W<int>::template W<int>::X w4x;
+ // cxx98-error@-1 {{'template' keyword outside of a template}}
+ // cxx98-error@-2 {{'typename' occurs outside of a template}}
+
+ TT<W<int>::W> tt1;
+ // expected-error@-1 {{qualified reference to 'W' is a constructor name rather than a type in this context}}
+ TTy<W<int>::W> tt1a;
+ // expected-error@-1 {{qualified reference to 'W' is a constructor name rather than a type in this context}}
+ TT<W<int>::template W> tt2;
+ // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a template name in this context, despite preceding 'template' keyword}}
+ // cxx98-error@-2 {{'template' keyword outside of a template}}
TT<W<int>::WBase> tt3; TT<W<int>::WBase> tt3;
TTy<W<int>::WBase> tt3a; TTy<W<int>::WBase> tt3a;
- TT<W<int>::template WBase> tt4; // expected-error 0-1{{outside of a template}}+ TT<W<int>::template WBase> tt4;
+ // cxx98-error@-1 {{'template' keyword outside of a template}}
W<int> w; W<int> w;
(void)w.W::W::n; (void)w.W::W::n;
(void)w.W<int>::W::n; (void)w.W<int>::W::n;
(void)w.W<int>::W<int>::n; (void)w.W<int>::W<int>::n;
- (void)w.W<int>::template W<int>::n; // expected-error 0-1{{outside of a template}}+ (void)w.W<int>::template W<int>::n;
+ // cxx98-error@-1 {{'template' keyword outside of a template}}
} }
template<typename W> template<typename W>
void wt_test() { void wt_test() {
- typename W::W w2a; // expected-error {{qualified reference to 'W' is a constructor name}}+ typename W::W w2a;
- typename W::template W<int> w4; // expected-error {{qualified reference to 'W' is a constructor name}}+ // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a type in this context, despite preceding 'typename' keyword}}
- TTy<typename W::W> tt2; // expected-error {{qualified reference to 'W' is a constructor name}}+ // cxx98-note@#dr1310-W-int {{in instantiation of function template specialization 'dr1310::wt_test<dr1310::W<int> >' requested here}}
- TT<W::template W> tt3; // expected-error {{qualified reference to 'W' is a constructor name}}+ // since-cxx11-note@#dr1310-W-int {{in instantiation of function template specialization 'dr1310::wt_test<dr1310::W<int>>' requested here}}
+ typename W::template W<int> w4;
+ // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a template name in this context, despite preceding 'template' keyword}}
+ TTy<typename W::W> tt2;
+ // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a type in this context, despite preceding 'typename' keyword}}
+ TT<W::template W> tt3;
+ // expected-error@-1 {{ISO C++ specifies that qualified reference to 'W' is a constructor name rather than a template name in this context, despite preceding 'template' keyword}}
} }
template<typename W> template<typename W>
void wt_test_good() { void wt_test_good() {
@@ -111,18 +146,19 @@ namespace dr1310 { // dr1310: 5
(void)w.template W<int>::W::n; (void)w.template W<int>::W::n;
(void)w.template W<int>::template W<int>::n; (void)w.template W<int>::template W<int>::n;
} }
- template void wt_test<W<int> >(); // expected-note {{instantiation of}}+ template void wt_test<W<int> >(); // #dr1310-W-int
template void wt_test_good<W<int> >(); template void wt_test_good<W<int> >();
} }
namespace dr1315 { // dr1315: partial namespace dr1315 { // dr1315: partial
template <int I, int J> struct A {}; template <int I, int J> struct A {};
- template <int I> // expected-note {{non-deducible template parameter 'I'}}+ template <int I> struct A<I + 5, I * 2> {};
- struct A<I + 5, I * 2> {}; // expected-error {{contains a template parameter that cannot be deduced}}+ // expected-error@-1 {{class template partial specialization contains a template parameter that cannot be deduced; this partial specialization will never be used}}
+ // expected-note@-2 {{non-deducible template parameter 'I'}}
template <int I> struct A<I, I> {}; template <int I> struct A<I, I> {};
template <int I, int J, int K> struct B; template <int I, int J, int K> struct B;
- template <int I, int K> struct B<I, I * 2, K> {}; // expected-note {{matches}}+ template <int I, int K> struct B<I, I * 2, K> {}; // #dr1315-B-1
B<1, 2, 3> b1; B<1, 2, 3> b1;
// Multiple declarations with the same dependent expression are equivalent // Multiple declarations with the same dependent expression are equivalent
@@ -131,8 +167,11 @@ namespace dr1315 { // dr1315: partial
B<1, 2, 2>::type b2; B<1, 2, 2>::type b2;
// Multiple declarations with differing dependent expressions are unordered. // Multiple declarations with differing dependent expressions are unordered.
- template <int I, int K> struct B<I, I + 1, K> {}; // expected-note {{matches}}+ template <int I, int K> struct B<I, I + 1, K> {}; // #dr1315-B-2
- B<1, 2, 4> b3; // expected-error {{ambiguous}}+ B<1, 2, 4> b3;
+ // expected-error@-1 {{ambiguous partial specializations of 'B<1, 2, 4>'}}
+ // expected-note@#dr1315-B-1 {{partial specialization matches [with I = 1, K = 4]}}
+ // expected-note@#dr1315-B-2 {{partial specialization matches [with I = 1, K = 4]}}
// FIXME: Under dr1315, this is perhaps valid, but that is not clear: this // FIXME: Under dr1315, this is perhaps valid, but that is not clear: this
// fails the "more specialized than the primary template" test because the // fails the "more specialized than the primary template" test because the
@@ -146,7 +185,9 @@ namespace dr1315 { // dr1315: partial
namespace dr1330 { // dr1330: 4 c++11 namespace dr1330 { // dr1330: 4 c++11
// exception-specifications are parsed in a context where the class is complete. // exception-specifications are parsed in a context where the class is complete.
struct A { struct A {
- void f() throw(T) {} // expected-error 0-1{{C++17}} expected-note 0-1{{noexcept}}+ void f() throw(T) {}
+ // since-cxx17-error@-1 {{ISO C++17 does not allow dynamic exception specifications}}
+ // since-cxx17-note@-2 {{use 'noexcept(false)' instead}}
struct T {}; struct T {};
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
@@ -156,8 +197,12 @@ namespace dr1330 { // dr1330: 4 c++11
#endif #endif
}; };
- void (A::*af1)() throw(A::T) = &A::f; // expected-error 0-1{{C++17}} expected-note 0-1{{noexcept}}+ void (A::*af1)() throw(A::T) = &A::f;
- void (A::*af2)() throw() = &A::f; // expected-error-re {{{{not superset|different exception spec}}}}+ // since-cxx17-error@-1 {{ISO C++17 does not allow dynamic exception specifications}}
+ // since-cxx17-note@-2 {{use 'noexcept(false)' instead}}
+ void (A::*af2)() throw() = &A::f;
+ // cxx98-14-error@-1 {{target exception specification is not superset of source}}
+ // since-cxx17-error@-2 {{cannot initialize a variable of type 'void (dr1330::A::*)() throw()' with an rvalue of type 'void (dr1330::A::*)() throw(T)': different exception specifications}}
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
static_assert(noexcept(A().g()), ""); static_assert(noexcept(A().g()), "");
@@ -166,7 +211,9 @@ namespace dr1330 { // dr1330: 4 c++11
// Likewise, they're instantiated separately from an enclosing class template. // Likewise, they're instantiated separately from an enclosing class template.
template<typename U> template<typename U>
struct B { struct B {
- void f() throw(T, typename U::type) {} // expected-error 0-1{{C++17}} expected-note 0-1{{noexcept}}+ void f() throw(T, typename U::type) {}
+ // since-cxx17-error@-1 {{ISO C++17 does not allow dynamic exception specifications}}
+ // since-cxx17-note@-2 {{use 'noexcept(false)' instead}}
struct T {}; struct T {};
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
@@ -183,9 +230,6 @@ namespace dr1330 { // dr1330: 4 c++11
static const int value = true; static const int value = true;
}; };
- void (B<P>::*bpf1)() throw(B<P>::T, int) = &B<P>::f; // expected-error 0-1{{C++17}} expected-note 0-1{{noexcept}}
-#if __cplusplus < 201103L
- // expected-error@-2 {{not superset}}
// FIXME: We only delay instantiation in C++11 onwards. In C++98, something // FIXME: We only delay instantiation in C++11 onwards. In C++98, something
// weird happens: instantiation of B<P> fails because it references T before // weird happens: instantiation of B<P> fails because it references T before
// it's instantiated, but the diagnostic is suppressed in // it's instantiated, but the diagnostic is suppressed in
@@ -193,20 +237,20 @@ namespace dr1330 { // dr1330: 4 c++11
// obviously a bad way to react to this situation; we should still producing // obviously a bad way to react to this situation; we should still producing
// the "T has not yet been instantiated" error here, rather than giving // the "T has not yet been instantiated" error here, rather than giving
// confusing errors later on. // confusing errors later on.
-#endif+ void (B<P>::*bpf1)() throw(B<P>::T, int) = &B<P>::f;
- void (B<P>::*bpf2)() throw(int) = &B<P>::f; // expected-error 0-1{{C++17}} expected-note 0-1{{noexcept}}+ // since-cxx17-error@-1 {{ISO C++17 does not allow dynamic exception specifications}}
-#if __cplusplus <= 201402L+ // since-cxx17-note@-2 {{use 'noexcept(false)' instead}}
- // expected-error@-2 {{not superset}}+ // cxx98-error@-3 {{target exception specification is not superset of source}}
-#else+
- // expected-warning@-4 {{not superset}}+ void (B<P>::*bpf2)() throw(int) = &B<P>::f;
-#endif+ // since-cxx17-error@-1 {{ISO C++17 does not allow dynamic exception specifications}}
+ // since-cxx17-note@-2 {{use 'noexcept(false)' instead}}
+ // cxx98-14-error@-3 {{target exception specification is not superset of source}}
+ // since-cxx17-warning@-4 {{target exception specification is not superset of source}}
void (B<P>::*bpf3)() = &B<P>::f; void (B<P>::*bpf3)() = &B<P>::f;
void (B<P>::*bpf4)() throw() = &B<P>::f; void (B<P>::*bpf4)() throw() = &B<P>::f;
-#if __cplusplus <= 201402L+ // cxx98-14-error@-1 {{target exception specification is not superset of source}}
- // expected-error@-2 {{not superset}}+ // since-cxx17-error@-2 {{cannot initialize a variable of type 'void (B<P>::*)() throw()' with an rvalue of type 'void (dr1330::B<dr1330::P>::*)() throw(T, typename P::type)': different exception specifications}}
-#else
- // expected-error@-4 {{different exception specifications}}
-#endif
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
static_assert(noexcept(B<P>().g()), ""); static_assert(noexcept(B<P>().g()), "");
@@ -214,57 +258,64 @@ namespace dr1330 { // dr1330: 4 c++11
static_assert(!noexcept(B<Q>().g()), ""); static_assert(!noexcept(B<Q>().g()), "");
#endif #endif
- template<typename T> int f() throw(typename T::error) { return 0; } // expected-error 1-4{{prior to '::'}} expected-note 0-1{{prior to '::'}} expected-note 0-1{{requested here}}+ template<typename T> int f() throw(typename T::error) { return 0; } // #dr1330-f
-#if __cplusplus > 201402L+ // expected-error@#dr1330-f {{type 'int' cannot be used prior to '::' because it has no members}}
- // expected-error@-2 0-1{{C++17}} expected-note@-2 0-1{{noexcept}}+ // cxx98-note@#dr1330-f-int {{in instantiation of function template specialization 'dr1330::f<int>' requested here}}
-#endif+ // since-cxx11-note@#dr1330-f-int {{in instantiation of exception specification for 'f<int>' requested here}}
+ // cxx98-14-error@#dr1330-f {{type 'short' cannot be used prior to '::' because it has no members}}
+ // cxx98-14-note@#dr1330-f-short {{in instantiation of function template specialization 'dr1330::f<short>' requested here}}
+ // cxx11-14-note@#dr1330-f {{in instantiation of exception specification for 'f<short>' requested here}}
+ // since-cxx11-error@#dr1330-f {{type 'char' cannot be used prior to '::' because it has no members}}
+ // since-cxx11-note@#dr1330-f-char {{in instantiation of exception specification for 'f<char>' requested here}}
+ // since-cxx11-error@#dr1330-f {{type 'float' cannot be used prior to '::' because it has no members}}
+ // since-cxx11-note@#dr1330-f-float {{in instantiation of exception specification for 'f<float>' requested here}}
+ // since-cxx17-error@#dr1330-f {{ISO C++17 does not allow dynamic exception specifications}}
+ // since-cxx17-note@#dr1330-f {{use 'noexcept(false)' instead}}
+
// An exception-specification is needed even if the function is only used in // An exception-specification is needed even if the function is only used in
// an unevaluated operand. // an unevaluated operand.
- int f1 = sizeof(f<int>()); // expected-note {{instantiation of}}+ int f1 = sizeof(f<int>()); // #dr1330-f-int
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
- decltype(f<char>()) f2; // expected-note {{instantiation of}}+ decltype(f<char>()) f2; // #dr1330-f-char
- bool f3 = noexcept(f<float>()); // expected-note {{instantiation of}}+ bool f3 = noexcept(f<float>()); /// #dr1330-f-float
#endif #endif
// In C++17 onwards, substituting explicit template arguments into the // In C++17 onwards, substituting explicit template arguments into the
// function type substitutes into the exception specification (because it's // function type substitutes into the exception specification (because it's
// part of the type). In earlier languages, we don't notice there's a problem // part of the type). In earlier languages, we don't notice there's a problem
// until we've already started to instantiate. // until we've already started to instantiate.
- template int f<short>();+ template int f<short>(); // #dr1330-f-short
-#if __cplusplus >= 201703L+ // since-cxx17-error@-1 {{explicit instantiation of 'f' does not refer to a function template, variable template, member function, member class, or static data member}}
- // expected-error@-2 {{does not refer to a function template}}+ // since-cxx17-note@#dr1330-f {{candidate template ignored: substitution failure [with T = short]: type 'short' cannot be used prior to '::' because it has no members}}
-#else
- // expected-note@-4 {{instantiation of}}
-#endif
template<typename T> struct C { template<typename T> struct C {
- C() throw(typename T::type); // expected-error 1-2{{prior to '::'}}+ C() throw(typename T::type); // #dr1330-C
-#if __cplusplus > 201402L+ // since-cxx17-error@-1 {{ISO C++17 does not allow dynamic exception specifications}}
- // expected-error@-2 0-1{{C++17}} expected-note@-2 0-1{{noexcept}}+ // since-cxx17-note@-2 {{use 'noexcept(false)' instead}}
-#endif+ // cxx98-error@#dr1330-C {{type 'void' cannot be used prior to '::' because it has no members}}
+ // cxx98-note@#dr1330-C-void {{in instantiation of template class 'dr1330::C<void>' requested here}}
+ // expected-error@#dr1330-C {{type 'int' cannot be used prior to '::' because it has no members}}
+ // cxx98-note@#dr1330-C-int {{in instantiation of template class 'dr1330::C<int>' requested here}}
+ // since-cxx11-note@#dr1330-C-int {{in instantiation of exception specification for 'C' requested here}}
+ // since-cxx11-note@#dr1330-e {{in evaluation of exception specification for 'dr1330::E::E' needed here}}
}; };
- struct D : C<void> {}; // ok+ struct D : C<void> {}; // #dr1330-C-void
-#if __cplusplus < 201103L
- // expected-note@-2 {{instantiation of}}
-#endif
void f(D &d) { d = d; } // ok void f(D &d) { d = d; } // ok
- struct E : C<int> {}; // expected-note {{in instantiation of}}+ struct E : C<int> {}; // #dr1330-C-int
-#if __cplusplus >= 201103L+ E e; // #dr1330-e
- E e; // expected-note {{needed here}}
-#endif
} }
namespace dr1341 { // dr1341: sup P0683R1 namespace dr1341 { // dr1341: sup P0683R1
#if __cplusplus >= 202002L #if __cplusplus >= 202002L
int a; int a;
-const int b = 0; // #dr1341-b-decl+const int b = 0; // #dr1341-b
struct S { struct S {
int x1 : 8 = 42; int x1 : 8 = 42;
int x2 : 8 { 42 }; int x2 : 8 { 42 };
int y1 : true ? 8 : a = 42; int y1 : true ? 8 : a = 42;
int y2 : true ? 8 : b = 42; int y2 : true ? 8 : b = 42;
- // expected-error@-1 {{cannot assign to variable 'b' with const-qualified type 'const int'}}+ // since-cxx20-error@-1 {{cannot assign to variable 'b' with const-qualified type 'const int'}}
- // expected-note@#dr1341-b-decl {{variable 'b' declared const here}}+ // since-cxx20-note@#dr1341-b {{variable 'b' declared const here}}
int y3 : (true ? 8 : b) = 42; int y3 : (true ? 8 : b) = 42;
int z : 1 || new int { 0 }; int z : 1 || new int { 0 };
}; };
@@ -272,44 +323,66 @@ struct S {
} }
namespace dr1346 { // dr1346: 3.5 namespace dr1346 { // dr1346: 3.5
- auto a(1); // expected-error 0-1{{extension}}+ auto a(1);
- auto b(1, 2); // expected-error {{multiple expressions}} expected-error 0-1{{extension}}+ // cxx98-error@-1 {{'auto' type specifier is a C++11 extension}}
+ auto b(1, 2);
+ // cxx98-error@-1 {{'auto' type specifier is a C++11 extension}}
+ // expected-error@-2 {{initializer for variable 'b' with type 'auto' contains multiple expressions}}
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
- auto c({}); // expected-error {{parenthesized initializer list}}+ auto c({});
- auto d({1}); // expected-error {{parenthesized initializer list}}+ // since-cxx11-error@-1 {{cannot deduce type for variable 'c' with type 'auto' from parenthesized initializer list}}
- auto e({1, 2}); // expected-error {{parenthesized initializer list}}+ auto d({1});
+ // since-cxx11-error@-1 {{cannot deduce type for variable 'd' with type 'auto' from parenthesized initializer list}}
+ auto e({1, 2});
+ // since-cxx11-error@-1 {{cannot deduce type for variable 'e' with type 'auto' from parenthesized initializer list}}
#endif #endif
- template<typename...Ts> void f(Ts ...ts) { // expected-error 0-1{{extension}}+ template<typename...Ts> void f(Ts ...ts) {
- auto x(ts...); // expected-error {{empty}} expected-error 0-1{{extension}}+ // cxx98-error@-1 {{variadic templates are a C++11 extension}}
+ auto x(ts...);
+ // cxx98-error@-1 {{'auto' type specifier is a C++11 extension}}
+ // expected-error@-2 {{initializer for variable 'x' with type 'auto' is empty}}
+ // expected-note@#dr1346-f {{in instantiation of function template specialization 'dr1346::f<>' requested here}}
} }
- template void f(); // expected-note {{instantiation}}+ template void f(); // #dr1346-f
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
void init_capture() { void init_capture() {
- [a(1)] {} (); // expected-error 0-1{{extension}}+ [a(1)] {} ();
- [b(1, 2)] {} (); // expected-error {{multiple expressions}} expected-error 0-1{{extension}}+ // cxx11-error@-1 {{initialized lambda captures are a C++14 extension}}
-#if __cplusplus >= 201103L+ [b(1, 2)] {} ();
- [c({})] {} (); // expected-error {{parenthesized initializer list}} expected-error 0-1{{extension}}+ // cxx11-error@-1 {{initialized lambda captures are a C++14 extension}}
- [d({1})] {} (); // expected-error {{parenthesized initializer list}} expected-error 0-1{{extension}}+ // since-cxx11-error@-2 {{initializer for lambda capture 'b' contains multiple expressions}}
- [e({1, 2})] {} (); // expected-error {{parenthesized initializer list}} expected-error 0-1{{extension}}+ [c({})] {} ();
-#endif+ // cxx11-error@-1 {{initialized lambda captures are a C++14 extension}}
+ // since-cxx11-error@-2 {{cannot deduce type for lambda capture 'c' from parenthesized initializer list}}
+ [d({1})] {} ();
+ // cxx11-error@-1 {{initialized lambda captures are a C++14 extension}}
+ // since-cxx11-error@-2 {{cannot deduce type for lambda capture 'd' from parenthesized initializer list}}
+ [e({1, 2})] {} ();
+ // cxx11-error@-1 {{initialized lambda captures are a C++14 extension}}
+ // since-cxx11-error@-2 {{cannot deduce type for lambda capture 'e' from parenthesized initializer list}}
} }
#endif #endif
} }
-namespace dr1347 { // dr1347: yes+namespace dr1347 { // dr1347: 3.1
- auto x = 5, *y = &x; // expected-error 0-1{{extension}}+ auto x = 5, *y = &x;
- auto z = y, *q = y; // expected-error {{'auto' deduced as 'int *' in declaration of 'z' and deduced as 'int' in declaration of 'q'}} expected-error 0-1{{extension}}+ // cxx98-error@-1 {{'auto' type specifier is a C++11 extension}}
+ auto z = y, *q = y;
+ // cxx98-error@-1 {{'auto' type specifier is a C++11 extension}}
+ // expected-error@-2 {{'auto' deduced as 'int *' in declaration of 'z' and deduced as 'int' in declaration of 'q'}}
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
- auto a = 5, b = {1, 2}; // expected-error {{'auto' deduced as 'int' in declaration of 'a' and deduced as 'std::initializer_list<int>' in declaration of 'b'}}+ auto a = 5, b = {1, 2};
- auto (*fp)(int) -> int, i = 0; // expected-error {{declaration with trailing return type must be the only declaration in its group}}+ // since-cxx11-error@-1 {{'auto' deduced as 'int' in declaration of 'a' and deduced as 'std::initializer_list<int>' in declaration of 'b'}}
+ auto (*fp)(int) -> int, i = 0;
+ // since-cxx11-error@-1 {{declaration with trailing return type must be the only declaration in its group}}
#endif #endif
} }
-namespace dr1358 { // dr1358: yes+namespace dr1358 { // dr1358: 3.1
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
struct Lit { constexpr operator int() const { return 0; } }; struct Lit { constexpr operator int() const { return 0; } };
- struct NonLit { NonLit(); operator int(); }; // expected-note 2{{no constexpr constructors}}+ struct NonLit { NonLit(); operator int(); }; // #dr1358-NonLit
struct NonConstexprConv { constexpr operator int() const; }; struct NonConstexprConv { constexpr operator int() const; };
struct Virt { virtual int f(int) const; }; struct Virt { virtual int f(int) const; };
@@ -336,8 +409,12 @@ namespace dr1358 { // dr1358: yes
// But the corresponding non-template cases are rejected. // But the corresponding non-template cases are rejected.
struct B : Virt { struct B : Virt {
int member; int member;
- constexpr B(NonLit u) : member(u) {} // expected-error {{not a literal type}}+ constexpr B(NonLit u) : member(u) {}
- constexpr NonLit f(NonLit u) const { return NonLit(); } // expected-error {{not a literal type}}+ // since-cxx11-error@-1 {{constexpr constructor's 1st parameter type 'NonLit' is not a literal type}}
+ // since-cxx11-note@#dr1358-NonLit {{'NonLit' is not literal because it is not an aggregate and has no constexpr constructors other than copy or move constructors}}
+ constexpr NonLit f(NonLit u) const { return NonLit(); }
+ // since-cxx11-error@-1 {{constexpr function's return type 'NonLit' is not a literal type}}
+ // since-cxx11-note@#dr1358-NonLit {{'NonLit' is not literal because it is not an aggregate and has no constexpr constructors other than copy or move constructors}}
}; };
#endif #endif
} }
@@ -345,65 +422,113 @@ namespace dr1358 { // dr1358: yes
namespace dr1359 { // dr1359: 3.5 namespace dr1359 { // dr1359: 3.5
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
union A { constexpr A() = default; }; union A { constexpr A() = default; };
- union B { constexpr B() = default; int a; }; // expected-error {{not constexpr}} expected-note 2{{candidate}}+ union B { constexpr B() = default; int a; }; // #dr1359-B
- union C { constexpr C() = default; int a, b; }; // expected-error {{not constexpr}} expected-note 2{{candidate}}+ // cxx11-17-error@-1 {{defaulted definition of default constructor is not constexpr}}
- struct X { constexpr X() = default; union {}; }; // expected-error {{does not declare anything}}+ union C { constexpr C() = default; int a, b; }; // #dr1359-C
- struct Y { constexpr Y() = default; union { int a; }; }; // expected-error {{not constexpr}} expected-note 2{{candidate}}+ // cxx11-17-error@-1 {{defaulted definition of default constructor is not constexpr}}
+ struct X { constexpr X() = default; union {}; };
+ // since-cxx11-error@-1 {{declaration does not declare anything}}
+ struct Y { constexpr Y() = default; union { int a; }; }; // #dr1359-Y
+ // cxx11-17-error@-1 {{defaulted definition of default constructor is not constexpr}}
constexpr A a = A(); constexpr A a = A();
- constexpr B b = B(); // expected-error {{no matching}}+ constexpr B b = B();
- constexpr C c = C(); // expected-error {{no matching}}+ // cxx11-17-error@-1 {{no matching constructor for initialization of 'B'}}
+ // cxx11-17-note@#dr1359-B {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided}}
+ // cxx11-17-note@#dr1359-B {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided}}
+ constexpr C c = C();
+ // cxx11-17-error@-1 {{no matching constructor for initialization of 'C'}}
+ // cxx11-17-note@#dr1359-C {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided}}
+ // cxx11-17-note@#dr1359-C {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided}}
constexpr X x = X(); constexpr X x = X();
- constexpr Y y = Y(); // expected-error {{no matching}}+ constexpr Y y = Y();
+ // cxx11-17-error@-1 {{no matching constructor for initialization of 'Y'}}
+ // cxx11-17-note@#dr1359-Y {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided}}
+ // cxx11-17-note@#dr1359-Y {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided}}
#endif #endif
} }
namespace dr1388 { // dr1388: 4 namespace dr1388 { // dr1388: 4
- template<typename A, typename ...T> void f(T..., A); // expected-note 1+{{candidate}} expected-error 0-1{{C++11}}+ template<typename A, typename ...T> void f(T..., A); // #dr1388-f
- template<typename ...T> void g(T..., int); // expected-note 1+{{candidate}} expected-error 0-1{{C++11}}+ // cxx98-error@-1 {{variadic templates are a C++11 extension}}
- template<typename ...T, typename A> void h(T..., A); // expected-note 1+{{candidate}} expected-error 0-1{{C++11}}+ template<typename ...T> void g(T..., int); // #dr1388-g
+ // cxx98-error@-1 {{variadic templates are a C++11 extension}}
+ template<typename ...T, typename A> void h(T..., A); // #dr1388-h
+ // cxx98-error@-1 {{variadic templates are a C++11 extension}}
void test_f() { void test_f() {
f(0); // ok, trailing parameter pack deduced to empty f(0); // ok, trailing parameter pack deduced to empty
- f(0, 0); // expected-error {{no matching}}+ f(0, 0);
+ // expected-error@-1 {{no matching function for call to 'f'}}
+ // expected-note@#dr1388-f {{candidate function [with A = int, T = <>] not viable: requires 1 argument, but 2 were provided}}
f<int>(0); f<int>(0);
- f<int>(0, 0); // expected-error {{no matching}}+ f<int>(0, 0);
+ // expected-error@-1 {{no matching function for call to 'f'}}
+ // expected-note@#dr1388-f {{candidate function [with A = int, T = <>] not viable: requires 1 argument, but 2 were provided}}
f<int, int>(0, 0); f<int, int>(0, 0);
- f<int, int, int>(0, 0); // expected-error {{no matching}}+ f<int, int, int>(0, 0);
+ // expected-error@-1 {{no matching function for call to 'f'}}
+ // expected-note@#dr1388-f {{candidate function [with A = int, T = <int, int>] not viable: requires 3 arguments, but 2 were provided}}
g(0); g(0);
- g(0, 0); // expected-error {{no matching}}+ g(0, 0);
+ // expected-error@-1 {{no matching function for call to 'g'}}
+ // expected-note@#dr1388-g {{candidate function [with T = <>] not viable: requires 1 argument, but 2 were provided}}
g<>(0); g<>(0);
- g<int>(0); // expected-error {{no matching}}+ g<int>(0);
+ // expected-error@-1 {{no matching function for call to 'g'}}
+ // expected-note@#dr1388-g {{candidate function [with T = <int>] not viable: requires 2 arguments, but 1 was provided}}
g<int>(0, 0); g<int>(0, 0);
h(0); h(0);
- h(0, 0); // expected-error {{no matching}}+ h(0, 0);
+ // expected-error@-1 {{no matching function for call to 'h'}}
+ // expected-note@#dr1388-h {{candidate function [with T = <>, A = int] not viable: requires 1 argument, but 2 were provided}}
h<int>(0, 0); h<int>(0, 0);
- h<int, int>(0, 0); // expected-error {{no matching}}+ h<int, int>(0, 0);
+ // expected-error@-1 {{no matching function for call to 'h'}}
+ // expected-note@#dr1388-h {{candidate template ignored: couldn't infer template argument 'A'}}
} }
// A non-trailing parameter pack is still a non-deduced context, even though // A non-trailing parameter pack is still a non-deduced context, even though
// we know exactly how many arguments correspond to it. // we know exactly how many arguments correspond to it.
template<typename T, typename U> struct pair {}; template<typename T, typename U> struct pair {};
- template<typename ...T> struct tuple { typedef char type; }; // expected-error 0-2{{C++11}}+ template<typename ...T> struct tuple { typedef char type; }; //
- template<typename ...T, typename ...U> void f_pair_1(pair<T, U>..., int); // expected-error 0-2{{C++11}} expected-note {{[with T = <int, long>]: deduced incomplete pack <(no value), (no value)> for template parameter 'U'}}+ // cxx98-error@-1 {{variadic templates are a C++11 extension}}
- template<typename ...T, typename U> void f_pair_2(pair<T, char>..., U); // expected-error 0-2{{C++11}}+ template<typename ...T, typename ...U> void f_pair_1(pair<T, U>..., int); // #dr1388-f-1
- template<typename ...T, typename ...U> void f_pair_3(pair<T, U>..., tuple<U...>); // expected-error 0-2{{C++11}} expected-note {{deduced packs of different lengths for parameter 'U' (<(no value), (no value)> vs. <char>)}}+ // cxx98-error@-1 {{variadic templates are a C++11 extension}}
- template<typename ...T> void f_pair_4(pair<T, char>..., T...); // expected-error 0-2{{C++11}} expected-note {{<int, long> vs. <int, long, const char *>}}+ // cxx98-error@-2 {{variadic templates are a C++11 extension}}
+ template<typename ...T, typename U> void f_pair_2(pair<T, char>..., U);
+ // cxx98-error@-1 {{variadic templates are a C++11 extension}}
+ template<typename ...T, typename ...U> void f_pair_3(pair<T, U>..., tuple<U...>); // #dr1388-f-3
+ // cxx98-error@-1 {{variadic templates are a C++11 extension}}
+ // cxx98-error@-2 {{variadic templates are a C++11 extension}}
+ template<typename ...T> void f_pair_4(pair<T, char>..., T...); // #dr1388-f-4
+ // cxx98-error@-1 {{variadic templates are a C++11 extension}}
void g(pair<int, char> a, pair<long, char> b, tuple<char, char> c) { void g(pair<int, char> a, pair<long, char> b, tuple<char, char> c) {
- f_pair_1<int, long>(a, b, 0); // expected-error {{no match}}+ f_pair_1<int, long>(a, b, 0);
+ // expected-error@-1 {{no matching function for call to 'f_pair_1'}}
+ // expected-note@#dr1388-f-1 {{candidate template ignored: substitution failure [with T = <int, long>]: deduced incomplete pack <(no value), (no value)> for template parameter 'U'}}
f_pair_2<int, long>(a, b, 0); f_pair_2<int, long>(a, b, 0);
f_pair_3<int, long>(a, b, c); f_pair_3<int, long>(a, b, c);
- f_pair_3<int, long>(a, b, tuple<char>()); // expected-error {{no match}}+ f_pair_3<int, long>(a, b, tuple<char>());
+ // expected-error@-1 {{no matching function for call to 'f_pair_3'}}
+ // expected-note@#dr1388-f-3 {{candidate template ignored: deduced packs of different lengths for parameter 'U' (<(no value), (no value)> vs. <char>)}}
f_pair_4<int, long>(a, b, 0, 0L); f_pair_4<int, long>(a, b, 0, 0L);
- f_pair_4<int, long>(a, b, 0, 0L, "foo"); // expected-error {{no match}}+ f_pair_4<int, long>(a, b, 0, 0L, "foo");
+ // expected-error@-1 {{no matching function for call to 'f_pair_4'}}
+ // expected-note@#dr1388-f-4 {{candidate template ignored: deduced packs of different lengths for parameter 'T' (<int, long> vs. <int, long, const char *>)}}
} }
} }
namespace dr1391 { // dr1391: partial namespace dr1391 { // dr1391: partial
struct A {}; struct B : A {}; struct A {}; struct B : A {};
- template<typename T> struct C { C(int); typename T::error error; }; // expected-error 2{{'::'}}+ template<typename T> struct C { C(int); typename T::error error; }; // #dr1391-C
+ // expected-error@#dr1391-C {{type 'int' cannot be used prior to '::' because it has no members}}
+ // expected-note@#dr1391-b {{in instantiation of template class 'dr1391::C<int>' requested here}}
+ // expected-note@#dr1391-b {{while substituting deduced template arguments into function template 'b' [with T = int]}}
+ // expected-error@#dr1391-C {{type 'double' cannot be used prior to '::' because it has no members}}
+ // expected-note@#dr1391-c {{in instantiation of template class 'dr1391::C<double>' requested here}}
template<typename T> struct D {}; template<typename T> struct D {};
// No deduction is performed for parameters with no deducible template-parameters, therefore types do not need to match. // No deduction is performed for parameters with no deducible template-parameters, therefore types do not need to match.
@@ -444,28 +569,36 @@ namespace dr1391 { // dr1391: partial
void test_b() { void test_b() {
b(0, 0); // ok, deduction fails prior to forming a conversion sequence and instantiating C<int> b(0, 0); // ok, deduction fails prior to forming a conversion sequence and instantiating C<int>
// FIXME: The "while substituting" note should point at the overload candidate. // FIXME: The "while substituting" note should point at the overload candidate.
- b<int>(0, 0); // expected-note {{instantiation of}} expected-note {{while substituting}}+ b<int>(0, 0); // #dr1391-b
} }
template<typename T> struct Id { typedef T type; }; template<typename T> struct Id { typedef T type; };
template<typename T> void c(T, typename Id<C<T> >::type); template<typename T> void c(T, typename Id<C<T> >::type);
void test_c() { void test_c() {
// Implicit conversion sequences for dependent types are checked later. // Implicit conversion sequences for dependent types are checked later.
- c(0.0, 0); // expected-note {{instantiation of}}+ c(0.0, 0); // #dr1391-c
} }
namespace partial_ordering { namespace partial_ordering {
// FIXME: Second template should be considered more specialized because non-dependent parameter is ignored. // FIXME: Second template should be considered more specialized because non-dependent parameter is ignored.
- template<typename T> int a(T, short) = delete; // expected-error 0-1{{extension}} expected-note {{candidate}}+ template<typename T> int a(T, short) = delete; // #dr1391-a-short
- template<typename T> int a(T*, char); // expected-note {{candidate}}+ // cxx98-error@-1 {{deleted function definitions are a C++11 extension}}
- int test_a = a((int*)0, 0); // FIXME: expected-error {{ambiguous}}+ template<typename T> int a(T*, char); // #dr1391-a-char
+ int test_a = a((int*)0, 0);
+ // expected-error@-1 {{call to 'a' is ambiguous}} FIXME
+ // expected-note@#dr1391-a-short {{candidate function [with T = int *] has been explicitly deleted}}
+ // expected-note@#dr1391-a-char {{candidate function [with T = int]}}
// FIXME: Second template should be considered more specialized: // FIXME: Second template should be considered more specialized:
// deducing #1 from #2 ignores the second P/A pair, so deduction succeeds, // deducing #1 from #2 ignores the second P/A pair, so deduction succeeds,
// deducing #2 from #1 fails to deduce T, so deduction fails. // deducing #2 from #1 fails to deduce T, so deduction fails.
- template<typename T> int b(T, int) = delete; // expected-error 0-1{{extension}} expected-note {{candidate}}+ template<typename T> int b(T, int) = delete; // #dr1391-b-int
- template<typename T, typename U> int b(T*, U); // expected-note {{candidate}}+ // cxx98-error@-1 {{deleted function definitions are a C++11 extension}}
- int test_b = b((int*)0, 0); // FIXME: expected-error {{ambiguous}}+ template<typename T, typename U> int b(T*, U); // #dr1391-b-U
+ int test_b = b((int*)0, 0);
+ // expected-error@-1 {{call to 'b' is ambiguous}} FIXME
+ // expected-note@#dr1391-b-int {{candidate function [with T = int *] has been explicitly deleted}}
+ // expected-note@#dr1391-b-U {{candidate function [with T = int, U = int]}}
// Unintended consequences: because partial ordering does not consider // Unintended consequences: because partial ordering does not consider
// explicit template arguments, and deduction from a non-dependent type // explicit template arguments, and deduction from a non-dependent type
@@ -499,26 +632,26 @@ namespace dr1395 { // dr1395: 16
namespace dr1397 { // dr1397: 3.2 namespace dr1397 { // dr1397: 3.2
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
-struct A { // #dr1397-struct-A+struct A {
- void *p = A{}; // #dr1397-void-p+// cxx11-error@-1 {{default member initializer for 'p' needed within definition of enclosing class 'A' outside of member functions}}
-#if __cplusplus == 201103L+// cxx11-note@#dr1397-p {{in evaluation of exception specification for 'dr1397::A::A' needed here}}
- // expected-error@#dr1397-struct-A {{default member initializer for 'p' needed within definition of enclosing class 'A' outside of member functions}}+// cxx11-note@#dr1397-p {{default member initializer declared here}}
- // expected-note@#dr1397-void-p {{in evaluation of exception specification for 'dr1397::A::A' needed here}}+ void *p = A{}; // #dr1397-p
- // expected-note@#dr1397-void-p {{default member initializer declared here}}+ // since-cxx14-error@-1 {{default member initializer for 'p' needed within definition of enclosing class 'A' outside of member functions}}
-#elif __cplusplus >= 201402L+ // since-cxx14-note@-2 {{default member initializer declared here}}
- // expected-error@#dr1397-void-p {{default member initializer for 'p' needed within definition of enclosing class 'A' outside of member functions}}
- // expected-note@#dr1397-void-p {{default member initializer declared here}}
-#endif
operator void*() const { return nullptr; } operator void*() const { return nullptr; }
}; };
#endif #endif
} // namespace dr1397 } // namespace dr1397
namespace dr1399 { // dr1399: dup 1388 namespace dr1399 { // dr1399: dup 1388
- template<typename ...T> void f(T..., int, T...) {} // expected-note {{candidate}} expected-error 0-1{{C++11}}+ template<typename ...T> void f(T..., int, T...) {} // #dr1399-f
+ // cxx98-error@-1 {{variadic templates are a C++11 extension}}
void g() { void g() {
f(0); f(0);
f<int>(0, 0, 0); f<int>(0, 0, 0);
- f(0, 0, 0); // expected-error {{no match}}+ f(0, 0, 0);
+ // expected-error@-1 {{no matching function for call to 'f'}}
+ // expected-note@#dr1399-f {{candidate template ignored: deduced packs of different lengths for parameter 'T' (<> vs. <int, int>)}}
} }
} }
clang/test/CXX/drs/dr14xx.cpp
@@ -1,8 +1,10 @@
-// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++98 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++11 %s -verify=expected,cxx11-17,since-cxx11, -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++14 %s -verify=expected,cxx14-17,cxx11-17,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++17 %s -verify=expected,cxx14-17,cxx11-17,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++2a %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors
namespace dr1413 { // dr1413: 12 namespace dr1413 { // dr1413: 12
template<int> struct Check { template<int> struct Check {
@@ -15,24 +17,41 @@ namespace dr1413 { // dr1413: 12
void d(); void d();
void f() { void f() {
- Check<true ? 0 : A::unknown_spec>::type *var1; // expected-error {{undeclared identifier 'var1'}}+ Check<true ? 0 : A::unknown_spec>::type *var1;
- Check<true ? 0 : a>::type *var2; // ok, variable declaration expected-note 0+{{here}}+ // expected-error@-1 {{use of undeclared identifier 'var1'}}
- Check<true ? 0 : b>::type *var3; // expected-error {{undeclared identifier 'var3'}}+
- Check<true ? 0 : ((void)c, 0)>::type *var4; // expected-error {{undeclared identifier 'var4'}}+ // ok, variable declaration
+ Check<true ? 0 : a>::type *var2; // #dr1413-var2
+ Check<true ? 0 : b>::type *var3;
+ // expected-error@-1 {{use of undeclared identifier 'var3'}}
+ // expected-note@#dr1413-var2 {{'var2' declared here}}
+ Check<true ? 0 : ((void)c, 0)>::type *var4;
+ // expected-error@-1 {{use of undeclared identifier 'var4'}}
+ // expected-note@#dr1413-var2 {{'var2' declared here}}
+
// value-dependent because of the implied type-dependent 'this->', not because of 'd' // value-dependent because of the implied type-dependent 'this->', not because of 'd'
- Check<true ? 0 : (d(), 0)>::type *var5; // expected-error {{undeclared identifier 'var5'}}+ Check<true ? 0 : (d(), 0)>::type *var5;
+ // expected-error@-1 {{use of undeclared identifier 'var5'}}
+ // expected-note@#dr1413-var2 {{'var2' declared here}}
+
// value-dependent because of the value-dependent '&' operator, not because of 'A::d' // value-dependent because of the value-dependent '&' operator, not because of 'A::d'
- Check<true ? 0 : (&A::d(), 0)>::type *var5; // expected-error {{undeclared identifier 'var5'}}+ Check<true ? 0 : (&A::d(), 0)>::type *var5;
+ // expected-error@-1 {{use of undeclared identifier 'var5'}}
+ // expected-note@#dr1413-var2 {{'var2' declared here}}
} }
}; };
} }
namespace dr1423 { // dr1423: 11 namespace dr1423 { // dr1423: 11
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
- bool b1 = nullptr; // expected-error {{cannot initialize}}+ bool b1 = nullptr;
- bool b2(nullptr); // expected-warning {{implicit conversion of nullptr constant to 'bool'}}+ // since-cxx11-error@-1 {{cannot initialize a variable of type 'bool' with an rvalue of type 'std::nullptr_t'}}
- bool b3 = {nullptr}; // expected-error {{cannot initialize}}+ bool b2(nullptr);
- bool b4{nullptr}; // expected-warning {{implicit conversion of nullptr constant to 'bool'}}+ // since-cxx11-warning@-1 {{implicit conversion of nullptr constant to 'bool'}}
+ bool b3 = {nullptr};
+ // since-cxx11-error@-1 {{cannot initialize a variable of type 'bool' with an rvalue of type 'std::nullptr_t'}}
+ bool b4{nullptr};
+ // since-cxx11-warning@-1 {{implicit conversion of nullptr constant to 'bool'}}
#endif #endif
} }
@@ -62,7 +81,8 @@ namespace dr1432 { // dr1432: 16
namespace dr1443 { // dr1443: yes namespace dr1443 { // dr1443: yes
struct A { struct A {
int i; int i;
- A() { void foo(int=i); } // expected-error {{default argument references 'this'}}+ A() { void foo(int=i); }
+ // expected-error@-1 {{default argument references 'this'}}
}; };
} }
@@ -70,49 +90,54 @@ namespace dr1460 { // dr1460: 3.5
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
namespace DRExample { namespace DRExample {
union A { union A {
- union {}; // expected-error {{does not declare anything}}+ union {};
- union {}; // expected-error {{does not declare anything}}+ // expected-error@-1 {{declaration does not declare anything}}
+ union {};
+ // expected-error@-1 {{declaration does not declare anything}}
constexpr A() {} constexpr A() {}
}; };
constexpr A a = A(); constexpr A a = A();
union B { union B {
- union {}; // expected-error {{does not declare anything}}+ union {};
- union {}; // expected-error {{does not declare anything}}+ // expected-error@-1 {{declaration does not declare anything}}
+ union {};
+ // expected-error@-1 {{declaration does not declare anything}}
constexpr B() = default; constexpr B() = default;
}; };
constexpr B b = B(); constexpr B b = B();
union C { union C {
- union {}; // expected-error {{does not declare anything}}+ union {};
- union {}; // expected-error {{does not declare anything}}+ // expected-error@-1 {{declaration does not declare anything}}
+ union {};
+ // expected-error@-1 {{declaration does not declare anything}}
}; };
constexpr C c = C(); constexpr C c = C();
-#if __cplusplus > 201103L+#if __cplusplus >= 201403L
constexpr void f() { C c; } constexpr void f() { C c; }
static_assert((f(), true), ""); static_assert((f(), true), "");
#endif #endif
} }
union A {}; union A {};
- union B { int n; }; // expected-note 0+{{here}}+ union B { int n; }; // #dr1460-B
union C { int n = 0; }; union C { int n = 0; };
- struct D { union {}; }; // expected-error {{does not declare anything}}+ struct D { union {}; };
- struct E { union { int n; }; }; // expected-note 0+{{here}}+ // expected-error@-1 {{declaration does not declare anything}}
+ struct E { union { int n; }; }; // #dr1460-E
struct F { union { int n = 0; }; }; struct F { union { int n = 0; }; };
struct X { struct X {
friend constexpr A::A() noexcept; friend constexpr A::A() noexcept;
friend constexpr B::B() noexcept; friend constexpr B::B() noexcept;
-#if __cplusplus <= 201703L+ // cxx11-17-error@-1 {{constexpr declaration of 'B' follows non-constexpr declaration}}
- // expected-error@-2 {{follows non-constexpr declaration}}+ // cxx11-17-note@#dr1460-B {{previous declaration is here}}
-#endif
friend constexpr C::C() noexcept; friend constexpr C::C() noexcept;
friend constexpr D::D() noexcept; friend constexpr D::D() noexcept;
friend constexpr E::E() noexcept; friend constexpr E::E() noexcept;
-#if __cplusplus <= 201703L+ // cxx11-17-error@-1 {{constexpr declaration of 'E' follows non-constexpr declaration}}
- // expected-error@-2 {{follows non-constexpr declaration}}+ // cxx11-17-note@#dr1460-E {{previous declaration is here}}
-#endif
friend constexpr F::F() noexcept; friend constexpr F::F() noexcept;
}; };
@@ -128,79 +153,77 @@ namespace dr1460 { // dr1460: 3.5
namespace Defaulted { namespace Defaulted {
union A { constexpr A() = default; }; union A { constexpr A() = default; };
union B { int n; constexpr B() = default; }; union B { int n; constexpr B() = default; };
-#if __cplusplus <= 201703L+ // cxx11-17-error@-1 {{defaulted definition of default constructor is not constexpr}}
- // expected-error@-2 {{not constexpr}}
-#endif
union C { int n = 0; constexpr C() = default; }; union C { int n = 0; constexpr C() = default; };
- struct D { union {}; constexpr D() = default; }; // expected-error {{does not declare anything}}+ struct D { union {}; constexpr D() = default; };
+ // expected-error@-1 {{declaration does not declare anything}}
struct E { union { int n; }; constexpr E() = default; }; struct E { union { int n; }; constexpr E() = default; };
-#if __cplusplus <= 201703L+ // cxx11-17-error@-1 {{defaulted definition of default constructor is not constexpr}}
- // expected-error@-2 {{not constexpr}}
-#endif
struct F { union { int n = 0; }; constexpr F() = default; }; struct F { union { int n = 0; }; constexpr F() = default; };
struct G { union { int n = 0; }; union { int m; }; constexpr G() = default; }; struct G { union { int n = 0; }; union { int m; }; constexpr G() = default; };
-#if __cplusplus <= 201703L+ // cxx11-17-error@-1 {{defaulted definition of default constructor is not constexpr}}
- // expected-error@-2 {{not constexpr}}
-#endif
struct H { struct H {
union { union {
int n = 0; int n = 0;
}; };
- union { // expected-note 0-2{{member not initialized}}+ union { // #dr1460-H-union
int m; int m;
}; };
constexpr H() {} constexpr H() {}
-#if __cplusplus <= 201703L+ // cxx11-17-error@-1 {{constexpr constructor that does not initialize all members is a C++20 extension}}
- // expected-error@-2 {{initialize all members}}+ // cxx11-17-note@#dr1460-H-union {{member not initialized by constructor}}
-#endif
constexpr H(bool) : m(1) {} constexpr H(bool) : m(1) {}
constexpr H(char) : n(1) {} constexpr H(char) : n(1) {}
-#if __cplusplus <= 201703L+ // cxx11-17-error@-1 {{constexpr constructor that does not initialize all members is a C++20 extension}}
- // expected-error@-2 {{initialize all members}}+ // cxx11-17-note@#dr1460-H-union {{member not initialized by constructor}}
-#endif
constexpr H(double) : m(1), n(1) {} constexpr H(double) : m(1), n(1) {}
}; };
} }
-#if __cplusplus > 201103L+#if __cplusplus >= 201403L
template<typename T> constexpr bool check() { template<typename T> constexpr bool check() {
- T t;+ T t; // #dr1460-t
-#if __cplusplus <= 201703L
- // expected-note-re@-2 2{{non-constexpr constructor '{{[BE]}}'}}
-#endif
return true; return true;
} }
static_assert(check<A>(), ""); static_assert(check<A>(), "");
- static_assert(check<B>(), "");+ static_assert(check<B>(), ""); // #dr1460-check-B
-#if __cplusplus <= 201703L+ // cxx14-17-error@-1 {{static assertion expression is not an integral constant expression}}
- // expected-error@-2 {{constant}} expected-note@-2 {{in call}}+ // cxx14-17-note@#dr1460-t {{non-constexpr constructor 'B' cannot be used in a constant expression}}
-#endif+ // cxx14-17-note@#dr1460-check-B {{in call to 'check<dr1460::B>()'}}
+ // cxx14-17-note@#dr1460-B {{declared here}}
static_assert(check<C>(), ""); static_assert(check<C>(), "");
static_assert(check<D>(), ""); static_assert(check<D>(), "");
- static_assert(check<E>(), "");+ static_assert(check<E>(), ""); // #dr1460-check-E
-#if __cplusplus <= 201703L+ // cxx14-17-error@-1 {{static assertion expression is not an integral constant expression}}
- // expected-error@-2 {{constant}} expected-note@-2 {{in call}}+ // cxx14-17-note@#dr1460-t {{non-constexpr constructor 'E' cannot be used in a constant expression}}
-#endif+ // cxx14-17-note@#dr1460-check-E {{in call to 'check<dr1460::E>()'}}
+ // cxx14-17-note@#dr1460-E {{declared here}}
static_assert(check<F>(), ""); static_assert(check<F>(), "");
#endif #endif
union G { union G {
- int a = 0; // expected-note {{previous initialization is here}}+ int a = 0; // #dr1460-G-a
- int b = 0; // expected-error {{initializing multiple members of union}}+ int b = 0;
+ // expected-error@-1 {{initializing multiple members of union}}
+ // expected-note@#dr1460-G-a {{previous initialization is here}}
}; };
union H { union H {
union { union {
- int a = 0; // expected-note {{previous initialization is here}}+ int a = 0; // #dr1460-H-a
}; };
union { union {
- int b = 0; // expected-error {{initializing multiple members of union}}+ int b = 0;
+ // expected-error@-1 {{initializing multiple members of union}}
+ // expected-note@#dr1460-H-a {{previous initialization is here}}
}; };
}; };
struct I { struct I {
union { union {
- int a = 0; // expected-note {{previous initialization is here}}+ int a = 0; // #dr1460-I-a
- int b = 0; // expected-error {{initializing multiple members of union}}+ int b = 0;
+ // expected-error@-1 {{initializing multiple members of union}}
+ // expected-note@#dr1460-I-a {{previous initialization is here}}
}; };
}; };
struct J { struct J {
@@ -223,14 +246,24 @@ namespace dr1460 { // dr1460: 3.5
constexpr B(const char*) {} constexpr B(const char*) {}
}; };
static_assert(B().a == 1, ""); static_assert(B().a == 1, "");
- static_assert(B().b == 2, ""); // expected-error {{constant}} expected-note {{read of}}+ static_assert(B().b == 2, "");
- static_assert(B('x').a == 0, ""); // expected-error {{constant}} expected-note {{read of}}+ // expected-error@-1 {{static assertion expression is not an integral constant expression}}
+ // expected-note@-2 {{read of member 'b' of union with active member 'a' is not allowed in a constant expression}}
+ static_assert(B('x').a == 0, "");
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}}
+ // expected-note@-2 {{read of member 'a' of union with active member 'b' is not allowed in a constant expression}}
static_assert(B('x').b == 4, ""); static_assert(B('x').b == 4, "");
- static_assert(B(123).b == 2, ""); // expected-error {{constant}} expected-note {{read of}}+ static_assert(B(123).b == 2, "");
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}}
+ // expected-note@-2 {{read of member 'b' of union with active member 'c' is not allowed in a constant expression}}
static_assert(B(123).c == 3, ""); static_assert(B(123).c == 3, "");
- static_assert(B("").a == 1, ""); // expected-error {{constant}} expected-note {{read of}}+ static_assert(B("").a == 1, "");
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}}
+ // expected-note@-2 {{read of member 'a' of union with active member 'b' is not allowed in a constant expression}}
static_assert(B("").b == 2, ""); static_assert(B("").b == 2, "");
- static_assert(B("").c == 3, ""); // expected-error {{constant}} expected-note {{read of}}+ static_assert(B("").c == 3, "");
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}}
+ // expected-note@-2 {{read of member 'c' of union with active member 'b' is not allowed in a constant expression}}
struct C { struct C {
union { int a, b = 2, c; }; union { int a, b = 2, c; };
@@ -243,31 +276,55 @@ namespace dr1460 { // dr1460: 3.5
}; };
static_assert(C().a == 1, ""); static_assert(C().a == 1, "");
- static_assert(C().b == 2, ""); // expected-error {{constant}} expected-note {{read of}}+ static_assert(C().b == 2, "");
- static_assert(C().d == 4, ""); // expected-error {{constant}} expected-note {{read of}}+ // expected-error@-1 {{static assertion expression is not an integral constant expression}}
+ // expected-note@-2 {{read of member 'b' of union with active member 'a' is not allowed in a constant expression}}
+ static_assert(C().d == 4, "");
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}}
+ // expected-note@-2 {{read of member 'd' of union with active member 'e' is not allowed in a constant expression}}
static_assert(C().e == 5, ""); static_assert(C().e == 5, "");
- static_assert(C('x').b == 2, ""); // expected-error {{constant}} expected-note {{read of}}+ static_assert(C('x').b == 2, "");
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}}
+ // expected-note@-2 {{read of member 'b' of union with active member 'c' is not allowed in a constant expression}}
static_assert(C('x').c == 3, ""); static_assert(C('x').c == 3, "");
- static_assert(C('x').d == 4, ""); // expected-error {{constant}} expected-note {{read of}}+ static_assert(C('x').d == 4, "");
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}}
+ // expected-note@-2 {{read of member 'd' of union with active member 'e' is not allowed in a constant expression}}
static_assert(C('x').e == 5, ""); static_assert(C('x').e == 5, "");
static_assert(C(1).b == 2, ""); static_assert(C(1).b == 2, "");
- static_assert(C(1).c == 3, ""); // expected-error {{constant}} expected-note {{read of}}+ static_assert(C(1).c == 3, "");
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}}
+ // expected-note@-2 {{read of member 'c' of union with active member 'b' is not allowed in a constant expression}}
static_assert(C(1).d == 4, ""); static_assert(C(1).d == 4, "");
- static_assert(C(1).e == 5, ""); // expected-error {{constant}} expected-note {{read of}}+ static_assert(C(1).e == 5, "");
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}}
+ // expected-note@-2 {{read of member 'e' of union with active member 'd' is not allowed in a constant expression}}
static_assert(C(1.f).b == 2, ""); static_assert(C(1.f).b == 2, "");
- static_assert(C(1.f).c == 3, ""); // expected-error {{constant}} expected-note {{read of}}+ static_assert(C(1.f).c == 3, "");
- static_assert(C(1.f).e == 5, ""); // expected-error {{constant}} expected-note {{read of}}+ // expected-error@-1 {{static assertion expression is not an integral constant expression}}
+ // expected-note@-2 {{read of member 'c' of union with active member 'b' is not allowed in a constant expression}}
+ static_assert(C(1.f).e == 5, "");
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}}
+ // expected-note@-2 {{read of member 'e' of union with active member 'f' is not allowed in a constant expression}}
static_assert(C(1.f).f == 6, ""); static_assert(C(1.f).f == 6, "");
- static_assert(C("").a == 1, ""); // expected-error {{constant}} expected-note {{read of}}+ static_assert(C("").a == 1, "");
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}}
+ // expected-note@-2 {{read of member 'a' of union with active member 'b' is not allowed in a constant expression}}
static_assert(C("").b == 2, ""); static_assert(C("").b == 2, "");
- static_assert(C("").c == 3, ""); // expected-error {{constant}} expected-note {{read of}}+ static_assert(C("").c == 3, "");
- static_assert(C("").d == 4, ""); // expected-error {{constant}} expected-note {{read of}}+ // expected-error@-1 {{static assertion expression is not an integral constant expression}}
+ // expected-note@-2 {{read of member 'c' of union with active member 'b' is not allowed in a constant expression}}
+ static_assert(C("").d == 4, "");
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}}
+ // expected-note@-2 {{read of member 'd' of union with active member 'e' is not allowed in a constant expression}}
static_assert(C("").e == 5, ""); static_assert(C("").e == 5, "");
- static_assert(C("").f == 6, ""); // expected-error {{constant}} expected-note {{read of}}+ static_assert(C("").f == 6, "");
+ // expected-error@-1 {{static assertion expression is not an integral constant expression}}
+ // expected-note@-2 {{read of member 'f' of union with active member 'e' is not allowed in a constant expression}}
struct D; struct D;
extern const D d; extern const D d;
@@ -315,8 +372,10 @@ namespace std {
const _E* end() const {return __begin_ + __size_;} const _E* end() const {return __begin_ + __size_;}
}; };
} // std } // std
+#endif
namespace dr1467 { // dr1467: 3.7 c++11 namespace dr1467 { // dr1467: 3.7 c++11
+#if __cplusplus >= 201103L
// Note that the change to [over.best.ics] was partially undone by DR2076; // Note that the change to [over.best.ics] was partially undone by DR2076;
// the resulting rule is tested with the tests for that change. // the resulting rule is tested with the tests for that change.
@@ -382,9 +441,12 @@ namespace dr1467 { // dr1467: 3.7 c++11
X x; X x;
X x2{x}; X x2{x};
- void f1(int); // expected-note {{candidate function}}+ void f1(int); // #dr1467-f1
- void f1(std::initializer_list<long>) = delete; // expected-note {{candidate function has been explicitly deleted}}+ void f1(std::initializer_list<long>) = delete; // #dr1467-f1-deleted
- void g1() { f1({42}); } // expected-error {{call to deleted function 'f1'}}+ void g1() { f1({42}); }
+ // since-cxx11-error@-1 {{call to deleted function 'f1'}}
+ // since-cxx11-note@#dr1467-f1 {{candidate function}}
+ // since-cxx11-note@#dr1467-f1-deleted {{candidate function has been explicitly deleted}}
template <class T, class U> template <class T, class U>
struct Pair { struct Pair {
@@ -394,9 +456,12 @@ namespace dr1467 { // dr1467: 3.7 c++11
String(const char *); String(const char *);
}; };
- void f2(Pair<const char *, const char *>); // expected-note {{candidate function}}+ void f2(Pair<const char *, const char *>); // #dr1467-f2
- void f2(std::initializer_list<String>) = delete; // expected-note {{candidate function has been explicitly deleted}}+ void f2(std::initializer_list<String>) = delete; // #dr1467-f2-deleted
- void g2() { f2({"foo", "bar"}); } // expected-error {{call to deleted function 'f2'}}+ void g2() { f2({"foo", "bar"}); }
+ // since-cxx11-error@-1 {{call to deleted function 'f2'}}
+ // since-cxx11-note@#dr1467-f2 {{candidate function}}
+ // since-cxx11-note@#dr1467-f2-deleted {{candidate function has been explicitly deleted}}
} // dr_example } // dr_example
namespace nonaggregate { namespace nonaggregate {
@@ -453,84 +518,151 @@ namespace dr1467 { // dr1467: 3.7 c++11
} }
} // namespace NonAmbiguous } // namespace NonAmbiguous
-#if __cplusplus >= 201103L
namespace StringLiterals { namespace StringLiterals {
// When the array size is 4 the call will attempt to bind an lvalue to an // When the array size is 4 the call will attempt to bind an lvalue to an
// rvalue and fail. Therefore #2 will be called. (rsmith will bring this // rvalue and fail. Therefore #2 will be called. (rsmith will bring this
// issue to CWG) // issue to CWG)
- void f(const char(&&)[4]); // expected-note 2 {{expects an rvalue}} expected-note 3 {{no known conversion}}+ void f(const char(&&)[4]); // #dr1467-f-char-4
- void f(const char(&&)[5]) = delete; // expected-note 2 {{candidate function has been explicitly deleted}} expected-note 3 {{no known conversion}}+ void f(const char(&&)[5]) = delete; // #dr1467-f-char-5
- void f(const wchar_t(&&)[4]); // expected-note {{expects an rvalue}} expected-note 4 {{no known conversion}}+ void f(const wchar_t(&&)[4]); // #dr1467-f-wchar-4
- void f(const wchar_t(&&)[5]) = delete; // expected-note {{candidate function has been explicitly deleted}} expected-note 4 {{no known conversion}}+ void f(const wchar_t(&&)[5]) = delete; // #dr1467-f-wchar-5
#if __cplusplus >= 202002L #if __cplusplus >= 202002L
- void f2(const char8_t(&&)[4]); // expected-note {{expects an rvalue}}+ void f2(const char8_t(&&)[4]); // #dr1467-f2-char8-4
- void f2(const char8_t(&&)[5]) = delete; // expected-note {{candidate function has been explicitly deleted}}+ void f2(const char8_t(&&)[5]) = delete; // #dr1467-f2-char8-5
#endif #endif
- void f(const char16_t(&&)[4]); // expected-note {{expects an rvalue}} expected-note 4 {{no known conversion}}+ void f(const char16_t(&&)[4]); // #dr1467-f-char16-4
- void f(const char16_t(&&)[5]) = delete; // expected-note {{candidate function has been explicitly deleted}} expected-note 4 {{no known conversion}}+ void f(const char16_t(&&)[5]) = delete; // #dr1467-f-char16-5
- void f(const char32_t(&&)[4]); // expected-note {{expects an rvalue}} expected-note 4 {{no known conversion}}+ void f(const char32_t(&&)[4]); // #dr1467-f-char32-4
- void f(const char32_t(&&)[5]) = delete; // expected-note {{candidate function has been explicitly deleted}} expected-note 4 {{no known conversion}}+ void f(const char32_t(&&)[5]) = delete; // #dr1467-f-char32-5
void g() { void g() {
- f({"abc"}); // expected-error {{call to deleted function 'f'}}+ f({"abc"});
- f({((("abc")))}); // expected-error {{call to deleted function 'f'}}+ // since-cxx11-error@-1 {{call to deleted function 'f'}}
- f({L"abc"}); // expected-error {{call to deleted function 'f'}}+ // since-cxx11-note@#dr1467-f-char-5 {{candidate function has been explicitly deleted}}
+ // since-cxx11-note@#dr1467-f-char-4 {{candidate function not viable: expects an rvalue for 1st argument}}
+ // since-cxx11-note@#dr1467-f-wchar-4 {{candidate function not viable: no known conversion from 'const char[4]' to 'const wchar_t' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-wchar-5 {{candidate function not viable: no known conversion from 'const char[4]' to 'const wchar_t' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-char16-4 {{candidate function not viable: no known conversion from 'const char[4]' to 'const char16_t' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-char16-5 {{candidate function not viable: no known conversion from 'const char[4]' to 'const char16_t' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-char32-4 {{candidate function not viable: no known conversion from 'const char[4]' to 'const char32_t' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-char32-5 {{candidate function not viable: no known conversion from 'const char[4]' to 'const char32_t' for 1st argument}}
+ f({((("abc")))});
+ // since-cxx11-error@-1 {{call to deleted function 'f'}}
+ // since-cxx11-note@#dr1467-f-char-5 {{candidate function has been explicitly deleted}}
+ // since-cxx11-note@#dr1467-f-char-4 {{candidate function not viable: expects an rvalue for 1st argument}}
+ // since-cxx11-note@#dr1467-f-wchar-4 {{candidate function not viable: no known conversion from 'const char[4]' to 'const wchar_t' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-wchar-5 {{candidate function not viable: no known conversion from 'const char[4]' to 'const wchar_t' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-char16-4 {{candidate function not viable: no known conversion from 'const char[4]' to 'const char16_t' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-char16-5 {{candidate function not viable: no known conversion from 'const char[4]' to 'const char16_t' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-char32-4 {{candidate function not viable: no known conversion from 'const char[4]' to 'const char32_t' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-char32-5 {{candidate function not viable: no known conversion from 'const char[4]' to 'const char32_t' for 1st argument}}
+ f({L"abc"});
+ // since-cxx11-error@-1 {{call to deleted function 'f'}}
+ // since-cxx11-note@#dr1467-f-wchar-5 {{candidate function has been explicitly deleted}}
+ // since-cxx11-note@#dr1467-f-char-4 {{candidate function not viable: no known conversion from 'const wchar_t[4]' to 'const char' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-char-5 {{candidate function not viable: no known conversion from 'const wchar_t[4]' to 'const char' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-wchar-4 {{candidate function not viable: expects an rvalue for 1st argument}}
+ // since-cxx11-note@#dr1467-f-char16-4 {{candidate function not viable: no known conversion from 'const wchar_t[4]' to 'const char16_t' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-char16-5 {{candidate function not viable: no known conversion from 'const wchar_t[4]' to 'const char16_t' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-char32-4 {{candidate function not viable: no known conversion from 'const wchar_t[4]' to 'const char32_t' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-char32-5 {{candidate function not viable: no known conversion from 'const wchar_t[4]' to 'const char32_t' for 1st argument}}
#if __cplusplus >= 202002L #if __cplusplus >= 202002L
- f2({u8"abc"}); // expected-error {{call to deleted function 'f2'}}+ f2({u8"abc"});
+ // since-cxx20-error@-1 {{call to deleted function 'f2'}}
+ // since-cxx20-note@#dr1467-f2-char8-5 {{candidate function has been explicitly deleted}}
+ // since-cxx20-note@#dr1467-f2-char8-4 {{candidate function not viable: expects an rvalue for 1st argument}}
#endif #endif
- f({uR"(abc)"}); // expected-error {{call to deleted function 'f'}}+ f({uR"(abc)"});
- f({(UR"(abc)")}); // expected-error {{call to deleted function 'f'}}+ // since-cxx11-error@-1 {{call to deleted function 'f'}}
+ // since-cxx11-note@#dr1467-f-char16-5 {{candidate function has been explicitly deleted}}
+ // since-cxx11-note@#dr1467-f-char-4 {{candidate function not viable: no known conversion from 'const char16_t[4]' to 'const char' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-char-5 {{candidate function not viable: no known conversion from 'const char16_t[4]' to 'const char' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-wchar-4 {{candidate function not viable: no known conversion from 'const char16_t[4]' to 'const wchar_t' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-wchar-5 {{candidate function not viable: no known conversion from 'const char16_t[4]' to 'const wchar_t' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-char16-4 {{candidate function not viable: expects an rvalue for 1st argument}}
+ // since-cxx11-note@#dr1467-f-char32-4 {{candidate function not viable: no known conversion from 'const char16_t[4]' to 'const char32_t' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-char32-5 {{candidate function not viable: no known conversion from 'const char16_t[4]' to 'const char32_t' for 1st argument}}
+ f({(UR"(abc)")});
+ // since-cxx11-error@-1 {{call to deleted function 'f'}}
+ // since-cxx11-note@#dr1467-f-char32-5 {{candidate function has been explicitly deleted}}
+ // since-cxx11-note@#dr1467-f-char-4 {{candidate function not viable: no known conversion from 'const char32_t[4]' to 'const char' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-char-5 {{candidate function not viable: no known conversion from 'const char32_t[4]' to 'const char' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-wchar-4 {{candidate function not viable: no known conversion from 'const char32_t[4]' to 'const wchar_t' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-wchar-5 {{candidate function not viable: no known conversion from 'const char32_t[4]' to 'const wchar_t' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-char16-4 {{candidate function not viable: no known conversion from 'const char32_t[4]' to 'const char16_t' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-char16-5 {{candidate function not viable: no known conversion from 'const char32_t[4]' to 'const char16_t' for 1st argument}}
+ // since-cxx11-note@#dr1467-f-char32-4 {{candidate function not viable: expects an rvalue for 1st argument}}
} }
} // namespace StringLiterals } // namespace StringLiterals
#endif #endif
} // dr1467 } // dr1467
-namespace dr1479 { // dr1479: yes+namespace dr1479 { // dr1479: 3.1
- int operator"" _a(const char*, std::size_t = 0); // expected-error {{literal operator cannot have a default argument}}+#if __cplusplus >= 201103L
+ int operator"" _a(const char*, std::size_t = 0);
+ // since-cxx11-error@-1 {{literal operator cannot have a default argument}}
+#endif
} }
-namespace dr1482 { // dr1482: yes+namespace dr1482 { // dr1482: 3.0
// NB: sup 2516, test reused there // NB: sup 2516, test reused there
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
template <typename T> struct S { template <typename T> struct S {
typedef char I; typedef char I;
}; };
enum E2 : S<E2>::I { e }; enum E2 : S<E2>::I { e };
-// expected-error@-1 {{use of undeclared identifier 'E2'}}+// since-cxx11-error@-1 {{use of undeclared identifier 'E2'}}
#endif #endif
} // namespace dr1482 } // namespace dr1482
namespace dr1490 { // dr1490: 3.7 c++11 namespace dr1490 { // dr1490: 3.7 c++11
+#if __cplusplus >= 201103L
// List-initialization from a string literal // List-initialization from a string literal
- char s[4]{"abc"}; // Ok+ char s[4]{"abc"}; // Ok
- std::initializer_list<char>{"abc"}; // expected-error {{expected unqualified-id}}}+ std::initializer_list<char>{"abc"};
+ // since-cxx11-error@-1 {{expected unqualified-id}}}
+#endif
} // dr1490 } // dr1490
namespace dr1495 { // dr1495: 4 namespace dr1495 { // dr1495: 4
+#if __cplusplus >= 201103L
// Deduction succeeds in both directions. // Deduction succeeds in both directions.
- template<typename T, typename U> struct A {}; // expected-note {{template is declared here}}+ template<typename T, typename U> struct A {}; // #dr1495-A
- template<typename T, typename U> struct A<U, T> {}; // expected-error {{class template partial specialization is not more specialized}}+ template<typename T, typename U> struct A<U, T> {};
+ // since-cxx11-error@-1 {{class template partial specialization is not more specialized than the primary template}}
+ // since-cxx11-note@#dr1495-A {{template is declared here}}
// Primary template is more specialized. // Primary template is more specialized.
- template<typename, typename...> struct B {}; // expected-note {{template is declared here}}+ template<typename, typename...> struct B {}; // #dr1495-B
- template<typename ...Ts> struct B<Ts...> {}; // expected-error {{not more specialized}}+ template<typename ...Ts> struct B<Ts...> {};
+ // since-cxx11-error@-1 {{class template partial specialization is not more specialized than the primary template}}
+ // since-cxx11-note@#dr1495-B {{template is declared here}}
// Deduction fails in both directions. // Deduction fails in both directions.
- template<int, typename, typename ...> struct C {}; // expected-note {{template is declared here}}+ template<int, typename, typename ...> struct C {}; // #dr1495-C
- template<typename ...Ts> struct C<0, Ts...> {}; // expected-error {{not more specialized}}+ template<typename ...Ts> struct C<0, Ts...> {};
+ // since-cxx11-error@-1 {{class template partial specialization is not more specialized than the primary template}}
+ // since-cxx11-note@#dr1495-C {{template is declared here}}
#if __cplusplus >= 201402L #if __cplusplus >= 201402L
// Deduction succeeds in both directions. // Deduction succeeds in both directions.
- template<typename T, typename U> int a; // expected-note {{template is declared here}}+ template<typename T, typename U> int a; // #dr1495-a
- template<typename T, typename U> int a<U, T>; // expected-error {{variable template partial specialization is not more specialized}}+ template<typename T, typename U> int a<U, T>;
+ // since-cxx14-error@-1 {{variable template partial specialization is not more specialized than the primary template}}
+ // since-cxx14-note@#dr1495-a {{template is declared here}}
// Primary template is more specialized. // Primary template is more specialized.
- template<typename, typename...> int b; // expected-note {{template is declared here}}+ template<typename, typename...> int b; // #dr1495-b
- template<typename ...Ts> int b<Ts...>; // expected-error {{not more specialized}}+ template<typename ...Ts> int b<Ts...>;
+ // since-cxx14-error@-1 {{variable template partial specialization is not more specialized than the primary template}}
+ // since-cxx14-note@#dr1495-b {{template is declared here}}
// Deduction fails in both directions. // Deduction fails in both directions.
- template<int, typename, typename ...> int c; // expected-note {{template is declared here}}+ template<int, typename, typename ...> int c; // #dr1495-c
- template<typename ...Ts> int c<0, Ts...>; // expected-error {{not more specialized}}+ template<typename ...Ts> int c<0, Ts...>;
+ // since-cxx14-error@-1 {{variable template partial specialization is not more specialized than the primary template}}
+ // since-cxx14-note@#dr1495-c {{template is declared here}}
+#endif
#endif #endif
} }
@@ -544,5 +676,3 @@ struct A {
static_assert(__is_trivial(A), ""); static_assert(__is_trivial(A), "");
#endif #endif
} }
-
-#endif
clang/test/CXX/drs/dr15xx.cpp
@@ -1,13 +1,18 @@
// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors // RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,cxx11-14 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,cxx14_17 -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,cxx11-14,cxx14-17 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,cxx17 -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx20,since-cxx11,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx20,since-cxx11,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx20,since-cxx11,since-cxx17 -fexceptions -fcxx-exceptions -pedantic-errors
namespace dr1512 { // dr1512: 4 namespace dr1512 { // dr1512: 4
void f(char *p) { void f(char *p) {
- if (p > 0) {} // expected-error {{ordered comparison between pointer and zero}}+ if (p > 0) {}
+ // expected-error@-1 {{ordered comparison between pointer and zero ('char *' and 'int')}}
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
- if (p > nullptr) {} // expected-error {{invalid operands}}+ if (p > nullptr) {}
+ // since-cxx11-error@-1 {{invalid operands to binary expression ('char *' and 'std::nullptr_t')}}
#endif #endif
} }
bool g(int **x, const int **y) { bool g(int **x, const int **y) {
@@ -28,10 +33,20 @@ namespace dr1512 { // dr1512: 4
template<typename A, typename B, typename C> void composite_pointer_type_is_ord() { template<typename A, typename B, typename C> void composite_pointer_type_is_ord() {
composite_pointer_type_is_base<A, B, C>(); composite_pointer_type_is_base<A, B, C>();
- typedef __typeof(val<A>() < val<B>()) cmp; // cxx17-warning 2 {{ordered comparison of function pointers}}+ typedef __typeof(val<A>() < val<B>()) cmp; // #dr1512-lt
- typedef __typeof(val<A>() <= val<B>()) cmp; // cxx17-warning 2 {{ordered comparison of function pointers}}+ // since-cxx17-warning@#dr1512-lt {{ordered comparison of function pointers ('int (*)() noexcept' and 'int (*)()')}}
- typedef __typeof(val<A>() > val<B>()) cmp; // cxx17-warning 2 {{ordered comparison of function pointers}}+ // since-cxx17-note@#dr1512-noexcept-1st {{in instantiation of function template specialization 'dr1512::composite_pointer_type_is_ord<int (*)() noexcept, int (*)(), int (*)()>' requested here}}
- typedef __typeof(val<A>() >= val<B>()) cmp; // cxx17-warning 2 {{ordered comparison of function pointers}}+ // since-cxx17-warning@#dr1512-lt {{ordered comparison of function pointers ('int (*)()' and 'int (*)() noexcept')}}
+ // since-cxx17-note@#dr1512-noexcept-2nd {{in instantiation of function template specialization 'dr1512::composite_pointer_type_is_ord<int (*)(), int (*)() noexcept, int (*)()>' requested here}}
+ typedef __typeof(val<A>() <= val<B>()) cmp;
+ // since-cxx17-warning@-1 {{ordered comparison of function pointers ('int (*)() noexcept' and 'int (*)()')}}
+ // since-cxx17-warning@-2 {{ordered comparison of function pointers ('int (*)()' and 'int (*)() noexcept')}}
+ typedef __typeof(val<A>() > val<B>()) cmp;
+ // since-cxx17-warning@-1 {{ordered comparison of function pointers ('int (*)() noexcept' and 'int (*)()')}}
+ // since-cxx17-warning@-2 {{ordered comparison of function pointers ('int (*)()' and 'int (*)() noexcept')}}
+ typedef __typeof(val<A>() >= val<B>()) cmp;
+ // since-cxx17-warning@-1 {{ordered comparison of function pointers ('int (*)() noexcept' and 'int (*)()')}}
+ // since-cxx17-warning@-2 {{ordered comparison of function pointers ('int (*)()' and 'int (*)() noexcept')}}
typedef bool cmp; typedef bool cmp;
} }
@@ -77,10 +92,11 @@ namespace dr1512 { // dr1512: 4
composite_pointer_type_is_unord<const int *B::*, volatile int *A::*, const volatile int *const B::*>(); composite_pointer_type_is_unord<const int *B::*, volatile int *A::*, const volatile int *const B::*>();
no_composite_pointer_type<int (A::*)(), int (C::*)()>(); no_composite_pointer_type<int (A::*)(), int (C::*)()>();
no_composite_pointer_type<const int (A::*)(), volatile int (C::*)()>(); no_composite_pointer_type<const int (A::*)(), volatile int (C::*)()>();
+ // since-cxx20-warning@-1 {{volatile-qualified return type 'volatile int' is deprecated}}
-#if __cplusplus > 201402+#if __cplusplus >= 201703L
- composite_pointer_type_is_ord<int (*)() noexcept, int (*)(), int (*)()>(); // expected-note {{requested here}}+ composite_pointer_type_is_ord<int (*)() noexcept, int (*)(), int (*)()>(); // #dr1512-noexcept-1st
- composite_pointer_type_is_ord<int (*)(), int (*)() noexcept, int (*)()>(); // expected-note {{requested here}}+ composite_pointer_type_is_ord<int (*)(), int (*)() noexcept, int (*)()>(); // #dr1512-noexcept-2nd
composite_pointer_type_is_unord<int (A::*)() noexcept, int (A::*)(), int (A::*)()>(); composite_pointer_type_is_unord<int (A::*)() noexcept, int (A::*)(), int (A::*)()>();
composite_pointer_type_is_unord<int (A::*)(), int (A::*)() noexcept, int (A::*)()>(); composite_pointer_type_is_unord<int (A::*)(), int (A::*)() noexcept, int (A::*)()>();
// FIXME: This looks like a standard defect; these should probably all have type 'int (B::*)()'. // FIXME: This looks like a standard defect; these should probably all have type 'int (B::*)()'.
@@ -113,24 +129,40 @@ namespace dr1512 { // dr1512: 4
} }
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
- template<typename T> struct Wrap { operator T(); }; // expected-note 4{{converted to type 'std::nullptr_t'}} expected-note 4{{converted to type 'int *'}}+ template<typename T> struct Wrap { operator T(); }; // #dr1512-Wrap
void test_overload() { void test_overload() {
using nullptr_t = decltype(nullptr); using nullptr_t = decltype(nullptr);
void(Wrap<nullptr_t>() == Wrap<nullptr_t>()); void(Wrap<nullptr_t>() == Wrap<nullptr_t>());
void(Wrap<nullptr_t>() != Wrap<nullptr_t>()); void(Wrap<nullptr_t>() != Wrap<nullptr_t>());
- void(Wrap<nullptr_t>() < Wrap<nullptr_t>()); // expected-error {{invalid operands}}+ void(Wrap<nullptr_t>() < Wrap<nullptr_t>());
- void(Wrap<nullptr_t>() > Wrap<nullptr_t>()); // expected-error {{invalid operands}}+ // since-cxx11-error@-1 {{invalid operands to binary expression ('Wrap<nullptr_t>' (aka 'Wrap<std::nullptr_t>') and 'Wrap<nullptr_t>' (aka 'Wrap<std::nullptr_t>'))}}
- void(Wrap<nullptr_t>() <= Wrap<nullptr_t>()); // expected-error {{invalid operands}}+ void(Wrap<nullptr_t>() > Wrap<nullptr_t>());
- void(Wrap<nullptr_t>() >= Wrap<nullptr_t>()); // expected-error {{invalid operands}}+ // since-cxx11-error@-1 {{invalid operands to binary expression ('Wrap<nullptr_t>' (aka 'Wrap<std::nullptr_t>') and 'Wrap<nullptr_t>' (aka 'Wrap<std::nullptr_t>'))}}
+ void(Wrap<nullptr_t>() <= Wrap<nullptr_t>());
+ // since-cxx11-error@-1 {{invalid operands to binary expression ('Wrap<nullptr_t>' (aka 'Wrap<std::nullptr_t>') and 'Wrap<nullptr_t>' (aka 'Wrap<std::nullptr_t>'))}}
+ void(Wrap<nullptr_t>() >= Wrap<nullptr_t>());
+ // since-cxx11-error@-1 {{invalid operands to binary expression ('Wrap<nullptr_t>' (aka 'Wrap<std::nullptr_t>') and 'Wrap<nullptr_t>' (aka 'Wrap<std::nullptr_t>'))}}
// Under dr1213, this is ill-formed: we select the builtin operator<(int*, int*) // Under dr1213, this is ill-formed: we select the builtin operator<(int*, int*)
// but then only convert as far as 'nullptr_t', which we then can't convert to 'int*'. // but then only convert as far as 'nullptr_t', which we then can't convert to 'int*'.
void(Wrap<nullptr_t>() == Wrap<int*>()); void(Wrap<nullptr_t>() == Wrap<int*>());
void(Wrap<nullptr_t>() != Wrap<int*>()); void(Wrap<nullptr_t>() != Wrap<int*>());
- void(Wrap<nullptr_t>() < Wrap<int*>()); // expected-error {{invalid operands to binary expression ('Wrap<nullptr_t>' (aka 'Wrap<std::nullptr_t>') and 'Wrap<int *>')}}+ void(Wrap<nullptr_t>() < Wrap<int*>());
- void(Wrap<nullptr_t>() > Wrap<int*>()); // expected-error {{invalid operands}}+ // since-cxx11-error@-1 {{invalid operands to binary expression ('Wrap<nullptr_t>' (aka 'Wrap<std::nullptr_t>') and 'Wrap<int *>')}}
- void(Wrap<nullptr_t>() <= Wrap<int*>()); // expected-error {{invalid operands}}+ // since-cxx11-note@#dr1512-Wrap {{first operand was implicitly converted to type 'std::nullptr_t'}}
- void(Wrap<nullptr_t>() >= Wrap<int*>()); // expected-error {{invalid operands}}+ // since-cxx11-note@#dr1512-Wrap {{second operand was implicitly converted to type 'int *'}}
+ void(Wrap<nullptr_t>() > Wrap<int*>());
+ // since-cxx11-error@-1 {{invalid operands}}
+ // since-cxx11-note@#dr1512-Wrap {{first operand was implicitly converted to type 'std::nullptr_t'}}
+ // since-cxx11-note@#dr1512-Wrap{{second operand was implicitly converted to type 'int *'}}
+ void(Wrap<nullptr_t>() <= Wrap<int*>());
+ // since-cxx11-error@-1 {{invalid operands}}
+ // since-cxx11-note@#dr1512-Wrap {{first operand was implicitly converted to type 'std::nullptr_t'}}
+ // since-cxx11-note@#dr1512-Wrap {{second operand was implicitly converted to type 'int *'}}
+ void(Wrap<nullptr_t>() >= Wrap<int*>());
+ // since-cxx11-error@-1 {{invalid operands}}
+ // since-cxx11-note@#dr1512-Wrap {{first operand was implicitly converted to type 'std::nullptr_t'}}
+ // since-cxx11-note@#dr1512-Wrap {{second operand was implicitly converted to type 'int *'}}
} }
#endif #endif
} }
@@ -138,8 +170,10 @@ namespace dr1512 { // dr1512: 4
namespace dr1514 { // dr1514: 11 namespace dr1514 { // dr1514: 11
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
struct S { struct S {
- enum E : int {}; // expected-note {{previous}}+ enum E : int {}; // #dr1514-E
- enum E : int {}; // expected-error {{redefinition}}+ enum E : int {};
+ // since-cxx11-error@-1 {{redefinition of 'E'}}
+ // since-cxx11-note@#dr1514-E {{previous definition is here}}
}; };
S::E se; // OK, complete type, not zero-width bitfield. S::E se; // OK, complete type, not zero-width bitfield.
@@ -149,91 +183,142 @@ namespace dr1514 { // dr1514: 11
namespace dr1518 { // dr1518: 4 namespace dr1518 { // dr1518: 4
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
-struct Z0 { // expected-note 0+ {{candidate}}+struct Z0 { // #dr1518-Z0
- explicit Z0() = default; // expected-note 0+ {{here}}+ explicit Z0() = default; // #dr1518-Z0-ctor
}; };
-struct Z { // expected-note 0+ {{candidate}}+struct Z { // #dr1518-Z
- explicit Z(); // expected-note 0+ {{here}}+ explicit Z(); // #dr1518-Z-ctor
- explicit Z(int); // expected-note {{not a candidate}}+ explicit Z(int); // #dr1518-Z-int
- explicit Z(int, int); // expected-note 0+ {{here}}+ explicit Z(int, int); // #dr1518-Z-int-int
}; };
-template <class T> int Eat(T); // expected-note 0+ {{candidate}}+template <class T> int Eat(T); // #dr1518-Eat
Z0 a; Z0 a;
Z0 b{}; Z0 b{};
-Z0 c = {}; // expected-error {{explicit in copy-initialization}}+Z0 c = {};
-int i = Eat<Z0>({}); // expected-error {{no matching function for call to 'Eat'}}+// since-cxx11-error@-1 {{chosen constructor is explicit in copy-initialization}}
-+// since-cxx11-note@#dr1518-Z0-ctor {{explicit constructor declared here}}
-Z c2 = {}; // expected-error {{explicit in copy-initialization}}+int i = Eat<Z0>({});
-int i2 = Eat<Z>({}); // expected-error {{no matching function for call to 'Eat'}}+// since-cxx11-error@-1 {{no matching function for call to 'Eat'}}
-Z a1 = 1; // expected-error {{no viable conversion}}+// since-cxx11-note@#dr1518-Eat {{candidate function template not viable: cannot convert initializer list argument to 'Z0'}}
+
+Z c2 = {};
+// since-cxx11-error@-1 {{chosen constructor is explicit in copy-initialization}}
+// since-cxx11-note@#dr1518-Z-ctor {{explicit constructor declared here}}
+int i2 = Eat<Z>({});
+// since-cxx11-error@-1 {{no matching function for call to 'Eat'}}
+// since-cxx11-note@#dr1518-Eat {{candidate function template not viable: cannot convert initializer list argument to 'Z'}}
+Z a1 = 1;
+// since-cxx11-error@-1 {{no viable conversion from 'int' to 'Z'}}
+// since-cxx11-note@#dr1518-Z {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const Z &' for 1st argument}}
+// since-cxx11-note@#dr1518-Z {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to 'Z &&' for 1st argument}}
+// since-cxx11-note@#dr1518-Z-int {{explicit constructor is not a candidate}}
Z a3 = Z(1); Z a3 = Z(1);
Z a2(1); Z a2(1);
Z *p = new Z(1); Z *p = new Z(1);
Z a4 = (Z)1; Z a4 = (Z)1;
Z a5 = static_cast<Z>(1); Z a5 = static_cast<Z>(1);
-Z a6 = {4, 3}; // expected-error {{explicit in copy-initialization}}+Z a6 = {4, 3};
+// since-cxx11-error@-1 {{chosen constructor is explicit in copy-initialization}}
+// since-cxx11-note@#dr1518-Z-int-int {{explicit constructor declared here}}
-struct UserProvidedBaseCtor { // expected-note 0+ {{candidate}}+struct UserProvidedBaseCtor { // #dr1518-U
UserProvidedBaseCtor() {} UserProvidedBaseCtor() {}
}; };
-struct DoesntInheritCtor : UserProvidedBaseCtor { // expected-note 0+ {{candidate}}+struct DoesntInheritCtor : UserProvidedBaseCtor { // #dr1518-D-U
int x; int x;
}; };
DoesntInheritCtor I{{}, 42}; DoesntInheritCtor I{{}, 42};
-#if __cplusplus <= 201402L+// cxx11-14-error@-1 {{no matching constructor for initialization of 'DoesntInheritCtor'}}
-// expected-error@-2 {{no matching constructor}}+// cxx11-14-note@#dr1518-D-U {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided}}
-#endif+// cxx11-14-note@#dr1518-D-U {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 2 were provided}}
-+// cxx11-14-note@#dr1518-D-U {{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 2 were provided}}
-struct BaseCtor { BaseCtor() = default; }; // expected-note 0+ {{candidate}}+
-struct InheritsCtor : BaseCtor { // expected-note 1+ {{candidate}}+struct BaseCtor { BaseCtor() = default; }; // #dr1518-BC
- using BaseCtor::BaseCtor; // expected-note 2 {{inherited here}}+struct InheritsCtor : BaseCtor { // #dr1518-I
+ using BaseCtor::BaseCtor; // #dr1518-I-using
int x; int x;
}; };
-InheritsCtor II = {{}, 42}; // expected-error {{no matching constructor}}+InheritsCtor II = {{}, 42};
+// since-cxx11-error@-1 {{no matching constructor for initialization of 'InheritsCtor'}}
+// since-cxx11-note@#dr1518-BC {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided}}
+// since-cxx11-note@#dr1518-I-using {{constructor from base class 'BaseCtor' inherited here}}
+// since-cxx11-note@#dr1518-BC {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 2 were provided}}
+// since-cxx11-note@#dr1518-I-using {{constructor from base class 'BaseCtor' inherited here}}
+// since-cxx11-note@#dr1518-I {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided}}
+// since-cxx11-note@#dr1518-I {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 2 were provided}}
+// since-cxx11-note@#dr1518-I {{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 2 were provided}}
namespace std_example { namespace std_example {
struct A { struct A {
- explicit A() = default; // expected-note 2{{declared here}}+ explicit A() = default; // #dr1518-A
}; };
struct B : A { struct B : A {
- explicit B() = default; // expected-note 2{{declared here}}+ explicit B() = default; // #dr1518-B
}; };
struct C { struct C {
- explicit C(); // expected-note 2{{declared here}}+ explicit C(); // #dr1518-C
}; };
struct D : A { struct D : A {
C c; C c;
- explicit D() = default; // expected-note 2{{declared here}}+ explicit D() = default; // #dr1518-D
}; };
template <typename T> void f() { template <typename T> void f() {
T t; // ok T t; // ok
T u{}; // ok T u{}; // ok
- T v = {}; // expected-error 4{{explicit}}+ T v = {}; // #dr1518-v
+ // since-cxx11-error@#dr1518-v {{chosen constructor is explicit in copy-initialization}}
+ // since-cxx11-note@#dr1518-f-A {{in instantiation of function template specialization 'dr1518::std_example::f<dr1518::std_example::A>' requested here}}
+ // since-cxx11-note@#dr1518-A {{explicit constructor declared here}}
+ // since-cxx11-error@#dr1518-v {{chosen constructor is explicit in copy-initialization}}
+ // since-cxx11-note@#dr1518-f-B {{in instantiation of function template specialization 'dr1518::std_example::f<dr1518::std_example::B>' requested here}}
+ // since-cxx11-note@#dr1518-B {{explicit constructor declared here}}
+ // since-cxx11-error@#dr1518-v {{chosen constructor is explicit in copy-initialization}}
+ // since-cxx11-note@#dr1518-f-C {{in instantiation of function template specialization 'dr1518::std_example::f<dr1518::std_example::C>' requested here}}
+ // since-cxx11-note@#dr1518-C {{explicit constructor declared here}}
+ // since-cxx11-error@#dr1518-v {{chosen constructor is explicit in copy-initialization}}
+ // since-cxx11-note@#dr1518-f-D {{in instantiation of function template specialization 'dr1518::std_example::f<dr1518::std_example::D>' requested here}}
+ // since-cxx11-note@#dr1518-D {{explicit constructor declared here}}
} }
template <typename T> void g() { template <typename T> void g() {
- void x(T t); // expected-note 4{{parameter}}+ void x(T t); // #dr1518-x
- x({}); // expected-error 4{{explicit}}+ x({}); // #dr1518-x-call
+ // since-cxx11-error@#dr1518-x-call {{chosen constructor is explicit in copy-initialization}}
+ // since-cxx11-note@#dr1518-g-A {{in instantiation of function template specialization 'dr1518::std_example::g<dr1518::std_example::A>' requested here}}
+ // since-cxx11-note@#dr1518-A {{explicit constructor declared here}}
+ // since-cxx11-note@#dr1518-x {{passing argument to parameter 't' here}}
+ // since-cxx11-error@#dr1518-x-call {{chosen constructor is explicit in copy-initialization}}
+ // since-cxx11-note@#dr1518-g-B {{in instantiation of function template specialization 'dr1518::std_example::g<dr1518::std_example::B>' requested here}}
+ // since-cxx11-note@#dr1518-B {{explicit constructor declared here}}
+ // since-cxx11-note@#dr1518-x {{passing argument to parameter 't' here}}
+ // since-cxx11-error@#dr1518-x-call {{chosen constructor is explicit in copy-initialization}}
+ // since-cxx11-note@#dr1518-g-C {{in instantiation of function template specialization 'dr1518::std_example::g<dr1518::std_example::C>' requested here}}
+ // since-cxx11-note@#dr1518-C {{explicit constructor declared here}}
+ // since-cxx11-note@#dr1518-x {{passing argument to parameter 't' here}}
+ // since-cxx11-error@#dr1518-x-call {{chosen constructor is explicit in copy-initialization}}
+ // since-cxx11-note@#dr1518-g-D {{in instantiation of function template specialization 'dr1518::std_example::g<dr1518::std_example::D>' requested here}}
+ // since-cxx11-note@#dr1518-D {{explicit constructor declared here}}
+ // since-cxx11-note@#dr1518-x {{passing argument to parameter 't' here}}
} }
void test() { void test() {
- f<A>(); // expected-note {{instantiation of}}+ f<A>(); // #dr1518-f-A
- f<B>(); // expected-note {{instantiation of}}+ f<B>(); // #dr1518-f-B
- f<C>(); // expected-note {{instantiation of}}+ f<C>(); // #dr1518-f-C
- f<D>(); // expected-note {{instantiation of}}+ f<D>(); // #dr1518-f-D
- g<A>(); // expected-note {{instantiation of}}+ g<A>(); // #dr1518-g-A
- g<B>(); // expected-note {{instantiation of}}+ g<B>(); // #dr1518-g-B
- g<C>(); // expected-note {{instantiation of}}+ g<C>(); // #dr1518-g-C
- g<D>(); // expected-note {{instantiation of}}+ g<D>(); // #dr1518-g-D
} }
} }
-#endif // __cplusplus >= 201103L+#endif // __cplusplus >= 201103L
} }
-namespace dr1550 { // dr1550: yes+namespace dr1550 { // dr1550: 3.4
int f(bool b, int n) { int f(bool b, int n) {
return (b ? (throw 0) : n) + (b ? n : (throw 0)); return (b ? (throw 0) : n) + (b ? n : (throw 0));
} }
@@ -242,13 +327,16 @@ namespace dr1550 { // dr1550: yes
namespace dr1558 { // dr1558: 12 namespace dr1558 { // dr1558: 12
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
template<class T, class...> using first_of = T; template<class T, class...> using first_of = T;
- template<class T> first_of<void, typename T::type> f(int); // expected-note {{'int' cannot be used prior to '::'}}+ template<class T> first_of<void, typename T::type> f(int); // #dr1558-f
- template<class T> void f(...) = delete; // expected-note {{deleted}}+ template<class T> void f(...) = delete; // #dr1558-f-deleted
struct X { typedef void type; }; struct X { typedef void type; };
void test() { void test() {
f<X>(0); f<X>(0);
- f<int>(0); // expected-error {{deleted}}+ f<int>(0);
+ // since-cxx11-error@-1 {{call to deleted function 'f'}}
+ // since-cxx11-note@#dr1558-f-deleted {{candidate function [with T = int] has been explicitly deleted}}
+ // since-cxx11-note@#dr1558-f {{candidate template ignored: substitution failure [with T = int]: type 'int' cannot be used prior to '::' because it has no members}}
} }
#endif #endif
} }
@@ -283,17 +371,25 @@ namespace dr1573 { // dr1573: 3.9
struct C { C(); constexpr C(int) {} }; struct C { C(); constexpr C(int) {} };
struct D : C { using C::C; }; struct D : C { using C::C; };
constexpr D d = D(0); // ok constexpr D d = D(0); // ok
- struct E : C { using C::C; A a; }; // expected-note {{non-literal type}}+ struct E : C { using C::C; A a; }; // #dr1573-E
- constexpr E e = E(0); // expected-error {{non-literal type}}+ constexpr E e = E(0);
+ // since-cxx11-error@-1 {{constexpr variable cannot have non-literal type 'const E'}}
+ // since-cxx11-note@#dr1573-E {{'E' is not literal because it has data member 'a' of non-literal type 'A'}}
+
// FIXME: This diagnostic is pretty bad; we should explain that the problem // FIXME: This diagnostic is pretty bad; we should explain that the problem
// is that F::c would be initialized by a non-constexpr constructor. // is that F::c would be initialized by a non-constexpr constructor.
- struct F : C { using C::C; C c; }; // expected-note {{here}}+ struct F : C { using C::C; C c; }; // #dr1573-F
- constexpr F f = F(0); // expected-error {{constant expression}} expected-note {{constructor inherited from base class 'C'}}+ constexpr F f = F(0);
+ // since-cxx11-error@-1 {{constexpr variable 'f' must be initialized by a constant expression}}
+ // since-cxx11-note@-2 {{constructor inherited from base class 'C' cannot be used in a constant expression; derived class cannot be implicitly initialized}}
+ // since-cxx11-note@#dr1573-F {{declared here}}
// inherited constructor is effectively deleted if the user-written constructor would be // inherited constructor is effectively deleted if the user-written constructor would be
struct G { G(int); }; struct G { G(int); };
- struct H : G { using G::G; G g; }; // expected-note {{constructor inherited by 'H' is implicitly deleted because field 'g' has no default constructor}}+ struct H : G { using G::G; G g; }; // #dr1573-H
- H h(0); // expected-error {{constructor inherited by 'H' from base class 'G' is implicitly deleted}}+ H h(0);
+ // since-cxx11-error@-1 {{constructor inherited by 'H' from base class 'G' is implicitly deleted}}
+ // since-cxx11-note@#dr1573-H {{constructor inherited by 'H' is implicitly deleted because field 'g' has no default constructor}}
#endif #endif
} }
@@ -336,13 +432,15 @@ namespace std {
typedef basic_string<char> string; typedef basic_string<char> string;
} // std } // std
+#endif
namespace dr1579 { // dr1579: 3.9 namespace dr1579 { // dr1579: 3.9
+#if __cplusplus >= 201103L
template<class T> template<class T>
struct GenericMoveOnly { struct GenericMoveOnly {
GenericMoveOnly(); GenericMoveOnly();
- template<class U> GenericMoveOnly(const GenericMoveOnly<U> &) = delete; // expected-note 5 {{marked deleted here}}+ template<class U> GenericMoveOnly(const GenericMoveOnly<U> &) = delete; // #dr1579-deleted-U
- GenericMoveOnly(const int &) = delete; // expected-note 2 {{marked deleted here}}+ GenericMoveOnly(const int &) = delete; // #dr1579-deleted-int
template<class U> GenericMoveOnly(GenericMoveOnly<U> &&); template<class U> GenericMoveOnly(GenericMoveOnly<U> &&);
GenericMoveOnly(int &&); GenericMoveOnly(int &&);
}; };
@@ -369,17 +467,29 @@ GenericMoveOnly<float> DR1579_Ineligible(int &AnInt,
extern GenericMoveOnly<char> ExternMove; extern GenericMoveOnly<char> ExternMove;
if (0) if (0)
- return AnInt; // expected-error{{invokes a deleted function}}+ return AnInt;
+ // since-cxx11-error@-1 {{conversion function from 'int' to 'GenericMoveOnly<float>' invokes a deleted function}}
+ // since-cxx11-note@#dr1579-deleted-int {{'GenericMoveOnly' has been explicitly marked deleted here}}
else if (0) else if (0)
- return GlobalMO; // expected-error{{invokes a deleted function}}+ return GlobalMO;
+ // since-cxx11-error@-1 {{conversion function from 'GenericMoveOnly<char>' to 'GenericMoveOnly<float>' invokes a deleted function}}
+ // since-cxx11-note@#dr1579-deleted-U {{'GenericMoveOnly<char>' has been explicitly marked deleted here}}
else if (0) else if (0)
- return StaticMove; // expected-error{{invokes a deleted function}}+ return StaticMove;
+ // since-cxx11-error@-1 {{conversion function from 'GenericMoveOnly<char>' to 'GenericMoveOnly<float>' invokes a deleted function}}
+ // since-cxx11-note@#dr1579-deleted-U {{'GenericMoveOnly<char>' has been explicitly marked deleted here}}
else if (0) else if (0)
- return ExternMove; // expected-error{{invokes a deleted function}}+ return ExternMove;
+ // since-cxx11-error@-1 {{conversion function from 'GenericMoveOnly<char>' to 'GenericMoveOnly<float>' invokes a deleted function}}
+ // since-cxx11-note@#dr1579-deleted-U {{'GenericMoveOnly<char>' has been explicitly marked deleted here}}
else if (0) else if (0)
- return AnInt; // expected-error{{invokes a deleted function}}+ return AnInt;
+ // since-cxx11-error@-1 {{conversion function from 'int' to 'GenericMoveOnly<float>' invokes a deleted function}}
+ // since-cxx11-note@#dr1579-deleted-int {{'GenericMoveOnly' has been explicitly marked deleted here}}
else else
- return CharMO; // expected-error{{invokes a deleted function}}+ return CharMO;
+ // since-cxx11-error@-1 {{conversion function from 'GenericMoveOnly<char>' to 'GenericMoveOnly<float>' invokes a deleted function}}
+ // since-cxx11-note@#dr1579-deleted-U {{'GenericMoveOnly<char>' has been explicitly marked deleted here}}
} }
auto DR1579_lambda_valid = [](GenericMoveOnly<float> mo) -> auto DR1579_lambda_valid = [](GenericMoveOnly<float> mo) ->
@@ -389,24 +499,34 @@ auto DR1579_lambda_valid = [](GenericMoveOnly<float> mo) ->
auto DR1579_lambda_invalid = []() -> GenericMoveOnly<char> { auto DR1579_lambda_invalid = []() -> GenericMoveOnly<char> {
static GenericMoveOnly<float> mo; static GenericMoveOnly<float> mo;
- return mo; // expected-error{{invokes a deleted function}}+ return mo;
+ // since-cxx11-error@-1 {{conversion function from 'GenericMoveOnly<float>' to 'GenericMoveOnly<char>' invokes a deleted function}}
+ // since-cxx11-note@#dr1579-deleted-U {{'GenericMoveOnly<float>' has been explicitly marked deleted here}}
}; };
+#endif
} // end namespace dr1579 } // end namespace dr1579
namespace dr1584 { namespace dr1584 {
+#if __cplusplus >= 201103L
// Deducing function types from cv-qualified types // Deducing function types from cv-qualified types
- template<typename T> void f(const T *); // expected-note {{candidate template ignored}}+ template<typename T> void f(const T *); // #dr1584-f
template<typename T> void g(T *, const T * = 0); template<typename T> void g(T *, const T * = 0);
- template<typename T> void h(T *) { T::error; } // expected-error {{no members}}+ template<typename T> void h(T *) { T::error; }
+ // since-cxx11-error@-1 {{type 'void ()' cannot be used prior to '::' because it has no members}}
+ // since-cxx11-note@#dr1584-h {{in instantiation of function template specialization 'dr1584::h<void ()>' requested here}}
template<typename T> void h(const T *); template<typename T> void h(const T *);
void i() { void i() {
- f(&i); // expected-error {{no matching function}}+ f(&i);
+ // since-cxx11-error@-1 {{no matching function for call to 'f'}}
+ // since-cxx11-note@#dr1584-f {{candidate template ignored: could not match 'const T *' against 'void (*)()'}}
g(&i); g(&i);
- h(&i); // expected-note {{here}}+ h(&i); // #dr1584-h
} }
+#endif
} }
namespace dr1589 { // dr1589: 3.7 c++11 namespace dr1589 { // dr1589: 3.7 c++11
+#if __cplusplus >= 201103L
// Ambiguous ranking of list-initialization sequences // Ambiguous ranking of list-initialization sequences
void f0(long, int=0); // Would makes selection of #0 ambiguous void f0(long, int=0); // Would makes selection of #0 ambiguous
@@ -425,25 +545,35 @@ namespace dr1589 { // dr1589: 3.7 c++11
void g2() { f2({"foo","bar"}); } // chooses #4 void g2() { f2({"foo","bar"}); } // chooses #4
namespace with_error { namespace with_error {
- void f0(long); // #0+ void f0(long);
- void f0(std::initializer_list<int>); // #00 expected-note {{candidate function}}+ void f0(std::initializer_list<int>); // #dr1589-f0-ilist
- void f0(std::initializer_list<int>, int = 0); // expected-note {{candidate function}}+ void f0(std::initializer_list<int>, int = 0); // #dr1589-f0-ilist-int
- void g0() { f0({1L}); } // expected-error{{call to 'f0' is ambiguous}}+ void g0() { f0({1L}); }
-+ // since-cxx11-error@-1 {{call to 'f0' is ambiguous}}
- void f1(int); // #1+ // since-cxx11-note@#dr1589-f0-ilist {{candidate function}}
- void f1(std::initializer_list<long>); // #2 expected-note {{candidate function}}+ // since-cxx11-note@#dr1589-f0-ilist-int {{candidate function}}
- void f1(std::initializer_list<long>, int = 0); // expected-note {{candidate function}}+
- void g1() { f1({42}); } // expected-error{{call to 'f1' is ambiguous}}+ void f1(int);
-+ void f1(std::initializer_list<long>); // #dr1589-f1-ilist
- void f2(std::pair<const char*, const char*>); // #3+ void f1(std::initializer_list<long>, int = 0); // #dr1589-f1-ilist-long
- void f2(std::initializer_list<std::string>); // #4 expected-note {{candidate function}}+ void g1() { f1({42}); }
- void f2(std::initializer_list<std::string>, int = 0); // expected-note {{candidate function}}+ // since-cxx11-error@-1 {{call to 'f1' is ambiguous}}
- void g2() { f2({"foo","bar"}); } // expected-error{{call to 'f2' is ambiguous}}+ // since-cxx11-note@#dr1589-f1-ilist {{candidate function}}
+ // since-cxx11-note@#dr1589-f1-ilist-long {{candidate function}}
+
+ void f2(std::pair<const char*, const char*>);
+ void f2(std::initializer_list<std::string>); // #dr1589-f2-ilist
+ void f2(std::initializer_list<std::string>, int = 0); // #dr1589-f2-ilist-int
+ void g2() { f2({"foo","bar"}); }
+ // since-cxx11-error@-1 {{call to 'f2' is ambiguous}}
+ // since-cxx11-note@#dr1589-f2-ilist {{candidate function}}
+ // since-cxx11-note@#dr1589-f2-ilist-int {{candidate function}}
} }
-+#endif
} // dr1589 } // dr1589
-namespace dr1591 { //dr1591. Deducing array bound and element type from initializer list +namespace dr1591 { //dr1591. Deducing array bound and element type from initializer list
+#if __cplusplus >= 201103L
template<class T, int N> int h(T const(&)[N]); template<class T, int N> int h(T const(&)[N]);
int X = h({1,2,3}); // T deduced to int, N deduced to 3 int X = h({1,2,3}); // T deduced to int, N deduced to 3
@@ -451,8 +581,10 @@ namespace dr1591 { //dr1591. Deducing array bound and element type from initial
int Y = j({42}); // T deduced to int, array bound not considered int Y = j({42}); // T deduced to int, array bound not considered
struct Aggr { int i; int j; }; struct Aggr { int i; int j; };
- template<int N> int k(Aggr const(&)[N]); //expected-note{{not viable}}+ template<int N> int k(Aggr const(&)[N]); // #dr1591-k
- int Y0 = k({1,2,3}); //expected-error{{no matching function}}+ int Y0 = k({1,2,3});
+ // since-cxx11-error@-1 {{no matching function for call to 'k'}}
+ // since-cxx11-note@#dr1591-k {{candidate function [with N = 3] not viable: no known conversion from 'int' to 'const Aggr' for 1st argument}}
int Z = k({{1},{2},{3}}); // OK, N deduced to 3 int Z = k({{1},{2},{3}}); // OK, N deduced to 3
template<int M, int N> int m(int const(&)[M][N]); template<int M, int N> int m(int const(&)[M][N]);
@@ -463,54 +595,64 @@ namespace dr1591 { //dr1591. Deducing array bound and element type from initial
namespace check_multi_dim_arrays { namespace check_multi_dim_arrays {
- template<class T, int N, int M, int O> int ***f(const T (&a)[N][M][O]); //expected-note{{deduced conflicting values}}+ template<class T, int N, int M, int O> int ***f(const T (&a)[N][M][O]); // #dr1591-f-3
- template<class T, int N, int M> int **f(const T (&a)[N][M]); //expected-note{{couldn't infer}}+ template<class T, int N, int M> int **f(const T (&a)[N][M]); // #dr1591-f-2
- template<class T, int N> int *f(const T (&a)[N]); //expected-note{{couldn't infer}}+ template<class T, int N> int *f(const T (&a)[N]); // #dr1591-f-1
int ***p3 = f({ { {1,2}, {3, 4} }, { {5,6}, {7, 8} }, { {9,10}, {11, 12} } }); int ***p3 = f({ { {1,2}, {3, 4} }, { {5,6}, {7, 8} }, { {9,10}, {11, 12} } });
- int ***p33 = f({ { {1,2}, {3, 4} }, { {5,6}, {7, 8} }, { {9,10}, {11, 12, 13} } }); //expected-error{{no matching}}+ int ***p33 = f({ { {1,2}, {3, 4} }, { {5,6}, {7, 8} }, { {9,10}, {11, 12, 13} } });
+ // since-cxx11-error@-1 {{no matching function for call to 'f'}}
+ // since-cxx11-note@#dr1591-f-2 {{candidate template ignored: couldn't infer template argument 'T'}}
+ // since-cxx11-note@#dr1591-f-1 {{candidate template ignored: couldn't infer template argument 'T'}}
+ // since-cxx11-note@#dr1591-f-3 {{candidate template ignored: deduced conflicting values for parameter 'O' (2 vs. 3)}}
int **p2 = f({ {1,2,3}, {3, 4, 5} }); int **p2 = f({ {1,2,3}, {3, 4, 5} });
int **p22 = f({ {1,2}, {3, 4} }); int **p22 = f({ {1,2}, {3, 4} });
int *p1 = f({1, 2, 3}); int *p1 = f({1, 2, 3});
} }
namespace check_multi_dim_arrays_rref { namespace check_multi_dim_arrays_rref {
- template<class T, int N, int M, int O> int ***f(T (&&a)[N][M][O]); //expected-note{{deduced conflicting values}}+ template<class T, int N, int M, int O> int ***g(T (&&a)[N][M][O]); // #dr1591-g-3
- template<class T, int N, int M> int **f(T (&&a)[N][M]); //expected-note{{couldn't infer}}+ template<class T, int N, int M> int **g(T (&&a)[N][M]); // #dr1591-g-2
- template<class T, int N> int *f(T (&&a)[N]); //expected-note{{couldn't infer}}+ template<class T, int N> int *g(T (&&a)[N]); // #dr1591-g-1
- int ***p3 = f({ { {1,2}, {3, 4} }, { {5,6}, {7, 8} }, { {9,10}, {11, 12} } });+ int ***p3 = g({ { {1,2}, {3, 4} }, { {5,6}, {7, 8} }, { {9,10}, {11, 12} } });
- int ***p33 = f({ { {1,2}, {3, 4} }, { {5,6}, {7, 8} }, { {9,10}, {11, 12, 13} } }); //expected-error{{no matching}}+ int ***p33 = g({ { {1,2}, {3, 4} }, { {5,6}, {7, 8} }, { {9,10}, {11, 12, 13} } });
- int **p2 = f({ {1,2,3}, {3, 4, 5} });+ // since-cxx11-error@-1 {{no matching function for call to 'g'}}
- int **p22 = f({ {1,2}, {3, 4} });+ // since-cxx11-note@#dr1591-g-2 {{candidate template ignored: couldn't infer template argument 'T'}}
- int *p1 = f({1, 2, 3});+ // since-cxx11-note@#dr1591-g-1 {{candidate template ignored: couldn't infer template argument 'T'}}
+ // since-cxx11-note@#dr1591-g-3 {{candidate template ignored: deduced conflicting values for parameter 'O' (2 vs. 3)}}
+ int **p2 = g({ {1,2,3}, {3, 4, 5} });
+ int **p22 = g({ {1,2}, {3, 4} });
+ int *p1 = g({1, 2, 3});
} }
namespace check_arrays_of_init_list { namespace check_arrays_of_init_list {
- template<class T, int N> float *f(const std::initializer_list<T> (&)[N]);+ template<class T, int N> float *h(const std::initializer_list<T> (&)[N]);
- template<class T, int N> double *f(const T(&)[N]);+ template<class T, int N> double *h(const T(&)[N]);
- double *p = f({1, 2, 3});+ double *p = h({1, 2, 3});
- float *fp = f({{1}, {1, 2}, {1, 2, 3}});+ float *fp = h({{1}, {1, 2}, {1, 2, 3}});
} }
namespace core_reflector_28543 { namespace core_reflector_28543 {
- template<class T, int N> int *f(T (&&)[N]); // #1+ template<class T, int N> int *i(T (&&)[N]); // #1
- template<class T> char *f(std::initializer_list<T> &&); //#2+ template<class T> char *i(std::initializer_list<T> &&); // #2
- template<class T, int N, int M> int **f(T (&&)[N][M]); //#3 expected-note{{candidate}}+ template<class T, int N, int M> int **i(T (&&)[N][M]); // #3 #dr1591-i-2
- template<class T, int N> char **f(std::initializer_list<T> (&&)[N]); //#4 expected-note{{candidate}}+ template<class T, int N> char **i(std::initializer_list<T> (&&)[N]); // #4 #dr1591-i-1
- template<class T> short *f(T (&&)[2]); //#5+ template<class T> short *i(T (&&)[2]); // #5
template<class T> using Arr = T[]; template<class T> using Arr = T[];
- char *pc = f({1, 2, 3}); // OK prefer #2 via 13.3.3.2 [over.ics.rank]+ char *pc = i({1, 2, 3}); // OK prefer #2 via 13.3.3.2 [over.ics.rank]
- char *pc2 = f({1, 2}); // #2 also + char *pc2 = i({1, 2}); // #2 also
- int *pi = f(Arr<int>{1, 2, 3}); // OK prefer #1+ int *pi = i(Arr<int>{1, 2, 3}); // OK prefer #1
- void *pv1 = f({ {1, 2, 3}, {4, 5, 6} }); // expected-error{{ambiguous}} btw 3 & 4+ void *pv1 = i({ {1, 2, 3}, {4, 5, 6} }); // ambiguous btw 3 & 4
- char **pcc = f({ {1}, {2, 3} }); // OK #4+ // since-cxx11-error@-1 {{call to 'i' is ambiguous}}
+ // since-cxx11-note@#dr1591-i-2 {{candidate function [with T = int, N = 2, M = 3]}}
+ // since-cxx11-note@#dr1591-i-1 {{candidate function [with T = int, N = 2]}}
+ char **pcc = i({ {1}, {2, 3} }); // OK #4
- short *ps = f(Arr<int>{1, 2}); // OK #5+ short *ps = i(Arr<int>{1, 2}); // OK #5
} }
-} // dr1591
-
#endif #endif
+} // dr1591
clang/test/CXX/drs/dr16xx.cpp
@@ -1,12 +1,14 @@
-// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected,cxx98-14,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify=expected,cxx98-14,since-cxx11,cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,cxx98-14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++2a -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-+// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-#if __cplusplus < 201103L+// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx14,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// expected-error@+1 {{variadic macro}}+
+#if __cplusplus == 199711L
#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__) #define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
+// cxx98-error@-1 {{variadic macros are a C99 feature}}
#endif #endif
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
@@ -25,9 +27,7 @@ namespace std {
namespace dr1601 { // dr1601: 10 namespace dr1601 { // dr1601: 10
enum E : char { e }; enum E : char { e };
-#if __cplusplus < 201103L+// cxx98-error@-1 {{enumeration types with a fixed underlying type are a C++11 extension}}
- // expected-error@-2 {{enumeration types with a fixed underlying type are a C++11 extension}}
-#endif
void f(char); void f(char);
void f(int); void f(int);
void g() { void g() {
@@ -53,26 +53,30 @@ namespace dr1631 { // dr1631: 3.7
void f(int, A); void f(int, A);
void test() { void test() {
- f({0}, {{1}}); // expected-warning {{braces around scalar init}}+ f({0}, {{1}});
+ // since-cxx11-warning@-1 {{braces around scalar initializer}}
} }
namespace with_error { namespace with_error {
void f(B, int); // TODO: expected- note {{candidate function}} void f(B, int); // TODO: expected- note {{candidate function}}
- void f(int, A); // expected-note {{candidate function}}+ void f(int, A); // #dr1631-f
- void f(int, A, int = 0); // expected-note {{candidate function}}+ void f(int, A, int = 0); // #dr1631-f-int
void test() { void test() {
- f({0}, {{1}}); // expected-error{{call to 'f' is ambiguous}}+ f({0}, {{1}});
+ // since-cxx11-error@-1 {{call to 'f' is ambiguous}}
+ // since-cxx11-note@#dr1631-f {{candidate function}}
+ // since-cxx11-note@#dr1631-f-int {{candidate function}}
} }
} }
#endif #endif
} }
-namespace dr1638 { // dr1638: yes+namespace dr1638 { // dr1638: 3.1
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
template<typename T> struct A { template<typename T> struct A {
- enum class E; // expected-note {{previous}}+ enum class E; // #dr1638-E
- enum class F : T; // expected-note 2{{previous}}+ enum class F : T; // #dr1638-F
}; };
template<> enum class A<int>::E; template<> enum class A<int>::E;
@@ -83,16 +87,27 @@ namespace dr1638 { // dr1638: yes
template<> enum class A<short>::E : int; template<> enum class A<short>::E : int;
template<> enum class A<short>::E : int {}; template<> enum class A<short>::E : int {};
- template<> enum class A<short>::F; // expected-error {{different underlying type}}+ template<> enum class A<short>::F;
- template<> enum class A<char>::E : char; // expected-error {{different underlying type}}+ // since-cxx11-error@-1 {{enumeration redeclared with different underlying type 'int' (was 'short')}}
- template<> enum class A<char>::F : int; // expected-error {{different underlying type}}+ // since-cxx11-note@#dr1638-F {{previous declaration is here}}
-+ template<> enum class A<char>::E : char;
- enum class A<unsigned>::E; // expected-error {{template specialization requires 'template<>'}} expected-error {{nested name specifier}}+ // since-cxx11-error@-1 {{enumeration redeclared with different underlying type 'char' (was 'int')}}
- template enum class A<unsigned>::E; // expected-error {{enumerations cannot be explicitly instantiated}}+ // since-cxx11-note@#dr1638-E {{previous declaration is here}}
- enum class A<unsigned>::E *e; // expected-error {{must use 'enum' not 'enum class'}}+ template<> enum class A<char>::F : int;
+ // since-cxx11-error@-1 {{enumeration redeclared with different underlying type 'int' (was 'char')}}
+ // since-cxx11-note@#dr1638-F {{previous declaration is here}}
+
+ enum class A<unsigned>::E;
+ // since-cxx11-error@-1 {{template specialization requires 'template<>'}}
+ // since-cxx11-error@-2 {{forward declaration of enum class cannot have a nested name specifier}}
+ template enum class A<unsigned>::E;
+ // since-cxx11-error@-1 {{enumerations cannot be explicitly instantiated}}
+ enum class A<unsigned>::E *e;
+ // since-cxx11-error@-1 {{reference to enumeration must use 'enum' not 'enum class'}}
struct B { struct B {
- friend enum class A<unsigned>::E; // expected-error {{must use 'enum' not 'enum class'}}+ friend enum class A<unsigned>::E;
+ // since-cxx11-error@-1 {{reference to enumeration must use 'enum' not 'enum class'}}
}; };
#endif #endif
} }
@@ -100,37 +115,50 @@ namespace dr1638 { // dr1638: yes
namespace dr1645 { // dr1645: 3.9 namespace dr1645 { // dr1645: 3.9
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
struct A { struct A {
- constexpr A(int, float = 0); // expected-note {{candidate}}+ constexpr A(int, float = 0); // #dr1645-int-float
- explicit A(int, int = 0); // expected-note 2{{candidate}}+ explicit A(int, int = 0); // #dr1645-int-int
- A(int, int, int = 0) = delete; // expected-note {{candidate}}+ A(int, int, int = 0) = delete; // #dr1645-int-int-int
}; };
struct B : A { struct B : A {
- using A::A; // expected-note 4{{inherited here}}+ using A::A; // #dr1645-using
}; };
- constexpr B a(0); // expected-error {{ambiguous}}+ constexpr B a(0);
- constexpr B b(0, 0); // expected-error {{ambiguous}}+ // since-cxx11-error@-1 {{call to constructor of 'const B' is ambiguous}}
+ // since-cxx11-note@#dr1645-int-float {{candidate inherited constructor}}
+ // since-cxx11-note@#dr1645-using {{constructor from base class 'A' inherited here}}
+ // since-cxx11-note@#dr1645-int-int {{candidate inherited constructor}}
+ // since-cxx11-note@#dr1645-using {{constructor from base class 'A' inherited here}}
+ constexpr B b(0, 0);
+ // since-cxx11-error@-1 {{call to constructor of 'const B' is ambiguous}}
+ // since-cxx11-note@#dr1645-int-int {{candidate inherited constructor}}
+ // since-cxx11-note@#dr1645-using {{constructor from base class 'A' inherited here}}
+ // since-cxx11-note@#dr1645-int-int-int {{candidate inherited constructor has been explicitly deleted}}
+ // since-cxx11-note@#dr1645-using {{constructor from base class 'A' inherited here}}
#endif #endif
} }
namespace dr1652 { // dr1652: 3.6 namespace dr1652 { // dr1652: 3.6
int a, b; int a, b;
- int arr[&a + 1 == &b ? 1 : 2]; // expected-error 2{{variable length array}}+ int arr[&a + 1 == &b ? 1 : 2];
- // expected-note@-1 {{points past the end}}+ // expected-error@-1 {{variable length arrays in C++ are a Clang extension}}
+ // expected-note@-2 {{comparison against pointer '&a + 1' that points past the end of a complete object has unspecified value}}
+ // expected-error@-3 {{variable length array declaration not allowed at file scope}}
} }
namespace dr1653 { // dr1653: 4 c++17 namespace dr1653 { // dr1653: 4 c++17
void f(bool b) { void f(bool b) {
++b; ++b;
+ // cxx98-14-warning@-1 {{incrementing expression of type bool is deprecated and incompatible with C++17}}
+ // since-cxx17-error@-2 {{SO C++17 does not allow incrementing expression of type bool}}
b++; b++;
-#if __cplusplus <= 201402L+ // cxx98-14-warning@-1 {{incrementing expression of type bool is deprecated and incompatible with C++17}}
- // expected-warning@-3 {{deprecated}} expected-warning@-2 {{deprecated}}+ // since-cxx17-error@-2 {{SO C++17 does not allow incrementing expression of type bool}}
-#else+ --b;
- // expected-error@-5 {{incrementing expression of type bool}} expected-error@-4 {{incrementing expression of type bool}}+ // expected-error@-1 {{cannot decrement expression of type bool}}
-#endif+ b--;
- --b; // expected-error {{cannot decrement expression of type bool}}+ // expected-error@-1 {{cannot decrement expression of type bool}}
- b--; // expected-error {{cannot decrement expression of type bool}}
b += 1; // ok b += 1; // ok
b -= 1; // ok b -= 1; // ok
} }
@@ -138,71 +166,88 @@ namespace dr1653 { // dr1653: 4 c++17
namespace dr1658 { // dr1658: 5 namespace dr1658 { // dr1658: 5
namespace DefCtor { namespace DefCtor {
- class A { A(); }; // expected-note 0-2{{here}}+ class A { A(); }; // #dr1658-A1
- class B { ~B(); }; // expected-note 0-2{{here}}+ class B { ~B(); }; // #dr1658-B1
// The stars align! An abstract class does not construct its virtual bases. // The stars align! An abstract class does not construct its virtual bases.
struct C : virtual A { C(); virtual void foo() = 0; }; struct C : virtual A { C(); virtual void foo() = 0; };
- C::C() = default; // ok, not deleted, expected-error 0-1{{extension}}+ C::C() = default; // ok, not deleted
+ // cxx98-error@-1 {{defaulted function definitions are a C++11 extension}}
struct D : virtual B { D(); virtual void foo() = 0; }; struct D : virtual B { D(); virtual void foo() = 0; };
- D::D() = default; // ok, not deleted, expected-error 0-1{{extension}}+ D::D() = default; // ok, not deleted
+ // cxx98-error@-1 {{defaulted function definitions are a C++11 extension}}
// In all other cases, we are not so lucky. // In all other cases, we are not so lucky.
- struct E : A { E(); virtual void foo() = 0; };+ struct E : A { E(); virtual void foo() = 0; }; // #dr1658-E1
-#if __cplusplus < 201103L+ E::E() = default; // #dr1658-E1-ctor
- E::E() = default; // expected-error {{private default constructor}} expected-error {{extension}} expected-note {{here}}+ // cxx98-error@-1 {{defaulted function definitions are a C++11 extension}}
-#else+ // cxx98-error@-2 {{base class 'A' has private default constructor}}
- E::E() = default; // expected-error {{would delete}} expected-note@-4{{inaccessible default constructor}}+ // cxx98-note@-3 {{in defaulted default constructor for 'dr1658::DefCtor::E' first required here}}
-#endif+ // cxx98-note@#dr1658-A1 {{implicitly declared private here}}
- struct F : virtual A { F(); };+ // since-cxx11-error@#dr1658-E1-ctor {{defaulting this default constructor would delete it after its first declaration}}
-#if __cplusplus < 201103L+ // since-cxx11-note@#dr1658-E1 {{default constructor of 'E' is implicitly deleted because base class 'A' has an inaccessible default constructor}}
- F::F() = default; // expected-error {{private default constructor}} expected-error {{extension}} expected-note {{here}}+ struct F : virtual A { F(); }; // #dr1658-F1
-#else+ F::F() = default; // #dr1658-F1-ctor
- F::F() = default; // expected-error {{would delete}} expected-note@-4{{inaccessible default constructor}}+ // cxx98-error@-1 {{defaulted function definitions are a C++11 extension}}
-#endif+ // cxx98-error@-2 {{inherited virtual base class 'A' has private default constructor}}
-+ // cxx98-note@-3 {{in defaulted default constructor for 'dr1658::DefCtor::F' first required here}}
- struct G : B { G(); virtual void foo() = 0; };+ // cxx98-note@#dr1658-A1 {{implicitly declared private here}}
-#if __cplusplus < 201103L+ // since-cxx11-error@#dr1658-F1-ctor {{defaulting this default constructor would delete it after its first declaration}}
- G::G() = default; // expected-error@-2 {{private destructor}} expected-error {{extension}} expected-note {{here}}+ // since-cxx11-note@#dr1658-F1 {{default constructor of 'F' is implicitly deleted because base class 'A' has an inaccessible default constructor}}
-#else+
- G::G() = default; // expected-error {{would delete}} expected-note@-4{{inaccessible destructor}}+ struct G : B { G(); virtual void foo() = 0; }; // #dr1658-G1
-#endif+ G::G() = default; // #dr1658-G1-ctor
- struct H : virtual B { H(); };+ // cxx98-error@-1 {{defaulted function definitions are a C++11 extension}}
-#if __cplusplus < 201103L+ // cxx98-error@#dr1658-G1 {{base class 'B' has private destructor}}
- H::H() = default; // expected-error@-2 {{private destructor}} expected-error {{extension}} expected-note {{here}}+ // cxx98-note@#dr1658-G1-ctor {{in defaulted default constructor for 'dr1658::DefCtor::G' first required here}}
-#else+ // cxx98-note@#dr1658-B1 {{implicitly declared private here}}
- H::H() = default; // expected-error {{would delete}} expected-note@-4{{inaccessible destructor}}+ // since-cxx11-error@#dr1658-G1-ctor {{defaulting this default constructor would delete it after its first declaration}}
-#endif+ // since-cxx11-note@#dr1658-G1 {{default constructor of 'G' is implicitly deleted because base class 'B' has an inaccessible destructor}}
+ struct H : virtual B { H(); }; // #dr1658-H1
+ H::H() = default; // #dr1658-H1-ctor
+ // cxx98-error@-1 {{defaulted function definitions are a C++11 extension}}
+ // cxx98-error@#dr1658-H1 {{base class 'B' has private destructor}}
+ // cxx98-note@#dr1658-H1-ctor {{in defaulted default constructor for 'dr1658::DefCtor::H' first required here}}
+ // cxx98-note@#dr1658-B1 {{implicitly declared private here}}
+ // since-cxx11-error@#dr1658-H1-ctor {{defaulting this default constructor would delete it after its first declaration}}
+ // since-cxx11-note@#dr1658-H1 {{default constructor of 'H' is implicitly deleted because base class 'B' has an inaccessible destructor}}
} }
namespace Dtor { namespace Dtor {
- class B { ~B(); }; // expected-note 0-2{{here}}+ class B { ~B(); }; // #dr1658-B2
struct D : virtual B { ~D(); virtual void foo() = 0; }; struct D : virtual B { ~D(); virtual void foo() = 0; };
- D::~D() = default; // ok, not deleted, expected-error 0-1{{extension}}+ D::~D() = default; // ok, not deleted
-+ // cxx98-error@-1 {{defaulted function definitions are a C++11 extension}}
- struct G : B { ~G(); virtual void foo() = 0; };+
-#if __cplusplus < 201103L+ struct G : B { ~G(); virtual void foo() = 0; }; // #dr1658-G2
- G::~G() = default; // expected-error@-2 {{private destructor}} expected-error {{extension}} expected-note {{here}}+ G::~G() = default; // #dr1658-G2-dtor
-#else+ // cxx98-error@-1 {{defaulted function definitions are a C++11 extension}}
- G::~G() = default; // expected-error {{would delete}} expected-note@-4{{inaccessible destructor}}+ // cxx98-error@#dr1658-G2 {{base class 'B' has private destructor}}
-#endif+ // cxx98-note@#dr1658-G2-dtor {{in defaulted destructor for 'dr1658::Dtor::G' first required here}}
- struct H : virtual B { ~H(); };+ // cxx98-note@#dr1658-B2 {{implicitly declared private here}}
-#if __cplusplus < 201103L+ // since-cxx11-error@#dr1658-G2-dtor {{defaulting this destructor would delete it after its first declaration}}
- H::~H() = default; // expected-error@-2 {{private destructor}} expected-error {{extension}} expected-note {{here}}+ // since-cxx11-note@#dr1658-G2 {{destructor of 'G' is implicitly deleted because base class 'B' has an inaccessible destructor}}
-#else+ struct H : virtual B { ~H(); }; // #dr1658-H2
- H::~H() = default; // expected-error {{would delete}} expected-note@-4{{inaccessible destructor}}+ H::~H() = default; // #dr1658-H2-dtor
-#endif+ // cxx98-error@-1 {{defaulted function definitions are a C++11 extension}}
+ // cxx98-error@#dr1658-H2 {{base class 'B' has private destructor}}
+ // cxx98-note@#dr1658-H2-dtor {{in defaulted destructor for 'dr1658::Dtor::H' first required here}}
+ // cxx98-note@#dr1658-B2 {{implicitly declared private here}}
+ // since-cxx11-error@#dr1658-H2-dtor {{defaulting this destructor would delete it after its first declaration}}
+ // since-cxx11-note@#dr1658-H2 {{destructor of 'H' is implicitly deleted because base class 'B' has an inaccessible destructor}}
} }
namespace MemInit { namespace MemInit {
- struct A { A(int); }; // expected-note {{here}}+ struct A { A(int); }; // #dr1658-A3
struct B : virtual A { struct B : virtual A {
B() {} B() {}
virtual void f() = 0; virtual void f() = 0;
}; };
struct C : virtual A { struct C : virtual A {
- C() {} // expected-error {{must explicitly initialize}}+ C() {}
+ // expected-error@-1 {{constructor for 'dr1658::MemInit::C' must explicitly initialize the base class 'A' which does not have a default constructor}}
+ // expected-note@#dr1658-A3 {{'dr1658::MemInit::A' declared here}}
}; };
} }
@@ -220,28 +265,51 @@ namespace dr1658 { // dr1658: 5
} }
namespace CopyCtor { namespace CopyCtor {
- class A { A(const A&); A(A&&); }; // expected-note 0-4{{here}} expected-error 0-1{{extension}}+ class A { A(const A&); A(A&&); }; // #dr1658-A5
-+ // cxx98-error@-1 {{rvalue references are a C++11 extension}}
- struct C : virtual A { C(const C&); C(C&&); virtual void foo() = 0; }; // expected-error 0-1{{extension}}+
- C::C(const C&) = default; // expected-error 0-1{{extension}}+ struct C : virtual A { C(const C&); C(C&&); virtual void foo() = 0; };
- C::C(C&&) = default; // expected-error 0-2{{extension}}+ // cxx98-error@-1 {{rvalue references are a C++11 extension}}
-+ C::C(const C&) = default;
- struct E : A { E(const E&); E(E&&); virtual void foo() = 0; }; // expected-error 0-1{{extension}}+ // cxx98-error@-1 {{defaulted function definitions are a C++11 extension}}
-#if __cplusplus < 201103L+ C::C(C&&) = default;
- E::E(const E&) = default; // expected-error {{private copy constructor}} expected-error {{extension}} expected-note {{here}}+ // cxx98-error@-1 {{rvalue references are a C++11 extension}}
- E::E(E&&) = default; // expected-error {{private move constructor}} expected-error 2{{extension}} expected-note {{here}}+ // cxx98-error@-2 {{defaulted function definitions are a C++11 extension}}
-#else+
- E::E(const E&) = default; // expected-error {{would delete}} expected-note@-5{{inaccessible copy constructor}}+ struct E : A { E(const E&); E(E&&); virtual void foo() = 0; }; // #dr1658-E5
- E::E(E&&) = default; // expected-error {{would delete}} expected-note@-6{{inaccessible move constructor}}+ // cxx98-error@-1 {{rvalue references are a C++11 extension}}
-#endif+ E::E(const E&) = default; // #dr1658-E5-copy-ctor
- struct F : virtual A { F(const F&); F(F&&); }; // expected-error 0-1{{extension}}+ // cxx98-error@-1 {{defaulted function definitions are a C++11 extension}}
-#if __cplusplus < 201103L+ // cxx98-error@-2 {{base class 'A' has private copy constructor}}
- F::F(const F&) = default; // expected-error {{private copy constructor}} expected-error {{extension}} expected-note {{here}}+ // cxx98-note@-3 {{in defaulted copy constructor for 'dr1658::CopyCtor::E' first required here}}
- F::F(F&&) = default; // expected-error {{private move constructor}} expected-error 2{{extension}} expected-note {{here}}+ // cxx98-note@#dr1658-A5 {{implicitly declared private here}}
-#else+ // since-cxx11-error@#dr1658-E5-copy-ctor {{defaulting this copy constructor would delete it after its first declaration}}
- F::F(const F&) = default; // expected-error {{would delete}} expected-note@-5{{inaccessible copy constructor}}+ // since-cxx11-note@#dr1658-E5 {{copy constructor of 'E' is implicitly deleted because base class 'A' has an inaccessible copy constructor}}
- F::F(F&&) = default; // expected-error {{would delete}} expected-note@-6{{inaccessible move constructor}}+ E::E(E&&) = default; // #dr1658-E5-move-ctor
-#endif+ // cxx98-error@-1 {{rvalue references are a C++11 extension}}
+ // cxx98-error@-2 {{defaulted function definitions are a C++11 extension}}
+ // cxx98-error@-3 {{base class 'A' has private move constructor}}
+ // cxx98-note@-4 {{in defaulted move constructor for 'dr1658::CopyCtor::E' first required here}}
+ // cxx98-note@#dr1658-A5 {{implicitly declared private here}}
+ // since-cxx11-error@#dr1658-E5-move-ctor {{defaulting this move constructor would delete it after its first declaration}}
+ // since-cxx11-note@#dr1658-E5 {{move constructor of 'E' is implicitly deleted because base class 'A' has an inaccessible move constructor}}
+ struct F : virtual A { F(const F&); F(F&&); }; // #dr1658-F5
+ // cxx98-error@-1 {{rvalue references are a C++11 extension}}
+ F::F(const F&) = default; // #dr1658-F5-copy-ctor
+ // cxx98-error@-1 {{defaulted function definitions are a C++11 extension}}
+ // cxx98-error@-2 {{inherited virtual base class 'A' has private copy constructor}}
+ // cxx98-note@-3 {{in defaulted copy constructor for 'dr1658::CopyCtor::F' first required here}}
+ // cxx98-note@#dr1658-A5 {{implicitly declared private here}}
+ // since-cxx11-error@#dr1658-F5-copy-ctor {{defaulting this copy constructor would delete it after its first declaration}}
+ // since-cxx11-note@#dr1658-F5 {{copy constructor of 'F' is implicitly deleted because base class 'A' has an inaccessible copy constructor}}
+ F::F(F&&) = default; // #dr1658-F5-move-ctor
+ // cxx98-error@-1 {{rvalue references are a C++11 extension}}
+ // cxx98-error@-2 {{defaulted function definitions are a C++11 extension}}
+ // cxx98-error@-3 {{inherited virtual base class 'A' has private move constructor}}
+ // cxx98-note@-4 {{in defaulted move constructor for 'dr1658::CopyCtor::F' first required here}}
+ // cxx98-note@#dr1658-A5 {{implicitly declared private here}}
+ // since-cxx11-error@#dr1658-F5-move-ctor {{defaulting this move constructor would delete it after its first declaration}}
+ // since-cxx11-note@#dr1658-F5 {{move constructor of 'F' is implicitly deleted because base class 'A' has an inaccessible move constructor}}
} }
// assignment case is superseded by dr2180 // assignment case is superseded by dr2180
@@ -274,31 +342,38 @@ namespace dr1672 { // dr1672: 7
namespace dr1684 { // dr1684: 3.6 namespace dr1684 { // dr1684: 3.6
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
- struct NonLiteral { // expected-note {{because}}+ struct NonLiteral { // #dr1684-struct
NonLiteral(); NonLiteral();
- constexpr int f() { return 0; } // expected-warning 0-1{{will not be implicitly 'const'}}+ constexpr int f() { return 0; }
+ // cxx11-warning@-1 {{'constexpr' non-static member function will not be implicitly 'const' in C++14; add 'const' to avoid a change in behavior}}
}; };
constexpr int f(NonLiteral &) { return 0; } constexpr int f(NonLiteral &) { return 0; }
- constexpr int f(NonLiteral) { return 0; } // expected-error {{not a literal type}}+ constexpr int f(NonLiteral) { return 0; }
+ // since-cxx11-error@-1 {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}}
+ // since-cxx11-note@#dr1684-struct {{'NonLiteral' is not literal because it is not an aggregate and has no constexpr constructors other than copy or move constructors}}
#endif #endif
} }
namespace dr1687 { // dr1687: 7 namespace dr1687 { // dr1687: 7
template<typename T> struct To { template<typename T> struct To {
- operator T(); // expected-note 2{{first operand was implicitly converted to type 'int *'}}+ operator T(); // #dr1687-op-T
- // expected-note@-1 {{second operand was implicitly converted to type 'double'}}
-#if __cplusplus > 201703L
- // expected-note@-3 2{{operand was implicitly converted to type 'dr1687::E}}
-#endif
}; };
- int *a = To<int*>() + 100.0; // expected-error {{invalid operands to binary expression ('To<int *>' and 'double')}}+ int *a = To<int*>() + 100.0;
- int *b = To<int*>() + To<double>(); // expected-error {{invalid operands to binary expression ('To<int *>' and 'To<double>')}}+ // expected-error@-1 {{invalid operands to binary expression ('To<int *>' and 'double')}}
+ // expected-note@#dr1687-op-T {{first operand was implicitly converted to type 'int *'}}
+ // since-cxx20-note@#dr1687-op-T {{second operand was implicitly converted to type 'dr1687::E2'}}
+ int *b = To<int*>() + To<double>();
+ // expected-error@-1 {{invalid operands to binary expression ('To<int *>' and 'To<double>')}}
+ // expected-note@#dr1687-op-T {{first operand was implicitly converted to type 'int *'}}
+ // expected-note@#dr1687-op-T {{second operand was implicitly converted to type 'double'}}
-#if __cplusplus > 201703L+#if __cplusplus >= 202002L
enum E1 {}; enum E1 {};
enum E2 {}; enum E2 {};
- auto c = To<E1>() <=> To<E2>(); // expected-error {{invalid operands to binary expression ('To<E1>' and 'To<E2>')}}+ auto c = To<E1>() <=> To<E2>();
+ // since-cxx20-error@-1 {{invalid operands to binary expression ('To<E1>' and 'To<E2>')}}
+ // since-cxx20-note@#dr1687-op-T {{operand was implicitly converted to type 'dr1687::E}}
#endif #endif
} }
@@ -325,12 +400,14 @@ namespace dr1691 { // dr1691: 9
void f(E); void f(E);
} }
enum M::E : int {}; enum M::E : int {};
- void g(M::E); // expected-note {{declared here}}+ void g(M::E); // #dr1691-g
} }
void test() { void test() {
N::M::E e; N::M::E e;
f(e); // ok f(e); // ok
- g(e); // expected-error {{use of undeclared}}+ g(e);
+ // since-cxx11-error@-1 {{use of undeclared identifier 'g'; did you mean 'N::g'?}}
+ // since-cxx11-note@#dr1691-g {{'N::g' declared here}}
} }
#endif #endif
} }
@@ -356,7 +433,9 @@ namespace dr1696 { // dr1696: 7
extern struct A a; extern struct A a;
struct A { struct A {
const A &x = { A{a, a} }; const A &x = { A{a, a} };
- const A &y = { A{} }; // expected-error {{default member initializer for 'y' needed within definition of enclosing class 'A' outside of member functions}} expected-note {{here}}+ const A &y = { A{} };
+ // since-cxx14-error@-1 {{default member initializer for 'y' needed within definition of enclosing class 'A' outside of member functions}}
+ // since-cxx14-note@-2 {{default member initializer declared here}}
}; };
A a{a, a}; A a{a, a};
#endif #endif
@@ -365,16 +444,20 @@ namespace dr1696 { // dr1696: 7
struct A { A(); ~A(); }; struct A { A(); ~A(); };
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
struct B { struct B {
- A &&a; // expected-note {{declared here}}+ A &&a; // #dr1696-a
- B() : a{} {} // expected-error {{reference member 'a' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}+ B() : a{} {}
+ // since-cxx11-error@-1 {{reference member 'a' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
+ // since-cxx11-note@#dr1696-a {{reference member declared here}}
} b; } b;
#endif #endif
struct C { struct C {
C(); C();
- const A &a; // expected-note {{declared here}}+ const A &a; // #dr1696-C-a
}; };
- C::C() : a(A()) {} // expected-error {{reference member 'a' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}+ C::C() : a(A()) {}
+ // expected-error@-1 {{reference member 'a' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
+ // expected-note@#dr1696-C-a {{reference member declared here}}
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
// This is OK in C++14 onwards, per DR1815, though we don't support that yet: // This is OK in C++14 onwards, per DR1815, though we don't support that yet:
@@ -383,51 +466,62 @@ namespace dr1696 { // dr1696: 7
// D1 d1 = {A()}; // D1 d1 = {A()};
// ... which lifetime-extends the A temporary. // ... which lifetime-extends the A temporary.
struct D1 { struct D1 {
-#if __cplusplus < 201402L+ // cxx11-error@-1 {{reference member 'a' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
- // expected-error@-2 {{binds to a temporary}}+ // cxx11-note@#dr1696-d1 {{in implicit default constructor for 'dr1696::D1' first required here}}
-#endif+ // cxx11-note@#dr1696-D1-a {{initializing field 'a' with default member initializer}}
- const A &a = A(); // expected-note {{default member init}}+ const A &a = A(); // #dr1696-D1-a
}; };
- D1 d1 = {};+ D1 d1 = {}; // #dr1696-d1
-#if __cplusplus < 201402L+ // since-cxx14-warning@-1 {{sorry, lifetime extension of temporary created by aggregate initialization using default member initializer is not supported; lifetime of temporary will end at the end of the full-expression}}
- // expected-note@-2 {{first required here}}+ // since-cxx14-note@#dr1696-D1-a {{initializing field 'a' with default member initializer}}
-#else
- // expected-warning-re@-4 {{sorry, lifetime extension {{.*}} not supported}}
-#endif
struct D2 { struct D2 {
- const A &a = A(); // expected-note {{default member init}}+ const A &a = A(); // #dr1696-D2-a
- D2() {} // expected-error {{binds to a temporary}}+ D2() {}
+ // since-cxx11-error@-1 {{reference member 'a' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
+ // since-cxx11-note@#dr1696-D2-a {{initializing field 'a' with default member initializer}}
}; };
- struct D3 { // expected-error {{binds to a temporary}}+ struct D3 {
- const A &a = A(); // expected-note {{default member init}}+ // since-cxx11-error@-1 {{reference member 'a' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
+ // since-cxx11-note@#dr1696-d3 {{in implicit default constructor for 'dr1696::D3' first required here}}
+ // since-cxx11-note@#dr1696-D3-a {{initializing field 'a' with default member initializer}}
+ const A &a = A(); // #dr1696-D3-a
}; };
- D3 d3; // expected-note {{first required here}}+ D3 d3; // #dr1696-d3
struct haslist1 { struct haslist1 {
- std::initializer_list<int> il; // expected-note {{'std::initializer_list' member}}+ std::initializer_list<int> il; // #dr1696-il-1
- haslist1(int i) : il{i, 2, 3} {} // expected-error {{backing array for 'std::initializer_list' member 'il' is a temporary object}}+ haslist1(int i) : il{i, 2, 3} {}
+ // since-cxx11-error@-1 {{backing array for 'std::initializer_list' member 'il' is a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
+ // since-cxx11-note@#dr1696-il-1 {{'std::initializer_list' member declared here}}
}; };
struct haslist2 { struct haslist2 {
- std::initializer_list<int> il; // expected-note {{'std::initializer_list' member}}+ std::initializer_list<int> il; // #dr1696-il-2
haslist2(); haslist2();
}; };
- haslist2::haslist2() : il{1, 2} {} // expected-error {{backing array for 'std::initializer_list' member 'il' is a temporary object}}+ haslist2::haslist2() : il{1, 2} {}
+ // since-cxx11-error@-1 {{backing array for 'std::initializer_list' member 'il' is a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
+ // since-cxx11-note@#dr1696-il-2 {{'std::initializer_list' member declared here}}
struct haslist3 { struct haslist3 {
std::initializer_list<int> il = {1, 2, 3}; std::initializer_list<int> il = {1, 2, 3};
}; };
- struct haslist4 { // expected-error {{backing array for 'std::initializer_list' member 'il' is a temporary object}}+ struct haslist4 {
- std::initializer_list<int> il = {1, 2, 3}; // expected-note {{default member initializer}}+ // since-cxx11-error@-1 {{backing array for 'std::initializer_list' member 'il' is a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
+ // since-cxx11-note@#dr1696-hl4 {{in implicit default constructor for 'dr1696::haslist4' first required here}}
+ // since-cxx11-note@#dr1696-il-4 {{initializing field 'il' with default member initializer}}
+ std::initializer_list<int> il = {1, 2, 3}; // #dr1696-il-4
}; };
- haslist4 hl4; // expected-note {{in implicit default constructor}}+ haslist4 hl4; // #dr1696-hl4
struct haslist5 { struct haslist5 {
- std::initializer_list<int> il = {1, 2, 3}; // expected-note {{default member initializer}}+ std::initializer_list<int> il = {1, 2, 3}; // #dr1696-il-5
- haslist5() {} // expected-error {{backing array for 'std::initializer_list' member 'il' is a temporary object}}+ haslist5() {}
+ // since-cxx11-error@-1 {{backing array for 'std::initializer_list' member 'il' is a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
+ // since-cxx11-note@#dr1696-il-5 {{nitializing field 'il' with default member initializer}}
}; };
#endif #endif
} }
clang/test/CXX/drs/dr17xx.cpp
@@ -1,10 +1,10 @@
-// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++98 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++11 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++14 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++20 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++23 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++2c %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
namespace dr1710 { // dr1710: no namespace dr1710 { // dr1710: no
// FIXME: all of the following is well-formed // FIXME: all of the following is well-formed
@@ -32,13 +32,17 @@ namespace dr1715 { // dr1715: 3.9
struct D : B { struct D : B {
using B::B; using B::B;
}; };
- struct E : B { // expected-note 2{{candidate}}+ struct E : B { // #dr1715-E
- template<class T> E(T t, typename T::Q q) : B(t, q) {} // expected-note {{'Q' is a private member}}+ template<class T> E(T t, typename T::Q q) : B(t, q) {} // #dr1715-E-ctor
}; };
B b(S(), 1); B b(S(), 1);
D d(S(), 2); D d(S(), 2);
- E e(S(), 3); // expected-error {{no match}}+ E e(S(), 3);
+ // since-cxx11-error@-1 {{no matching constructor for initialization of 'E'}}
+ // since-cxx11-note@#dr1715-E-ctor {{candidate template ignored: substitution failure [with T = S]: 'Q' is a private member of 'dr1715::S'}}
+ // since-cxx11-note@#dr1715-E {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided}}
+ // since-cxx11-note@#dr1715-E {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 2 were provided}}
#endif #endif
} }
@@ -73,12 +77,15 @@ struct S {
struct L : S { struct L : S {
using S::S; using S::S;
}; };
- typename T::type value; // expected-error {{no member}}+ typename T::type value;
- L l(value); // expected-note {{instantiation of}}+ // since-cxx11-error@-1 {{type 'int' cannot be used prior to '::' because it has no members}}
+ // since-cxx11-note@#dr1736-l {{in instantiation of function template specialization 'dr1736::S::S<int>' requested here}}
+ // since-cxx11-note@#dr1736-s {{in instantiation of function template specialization 'dr1736::S::S<dr1736::Q>' requested here}}
+ L l(value); // #dr1736-l
} }
}; };
struct Q { typedef int type; } q; struct Q { typedef int type; } q;
-S s(q); // expected-note {{instantiation of}}+S s(q); // #dr1736-s
#endif #endif
} }
@@ -91,18 +98,23 @@ namespace dr1753 { // dr1753: 11
n.~T(); n.~T();
n.T::~T(); n.T::~T();
- n.dr1753::~T(); // expected-error {{'dr1753' does not refer to a type name in pseudo-destructor}}+ n.dr1753::~T();
+ // expected-error@-1 {{'dr1753' does not refer to a type name in pseudo-destructor expression; expected the name of type 'T' (aka 'int')}}
n.dr1753::T::~T(); n.dr1753::T::~T();
- n.A::~T(); // expected-error {{the type of object expression ('T' (aka 'int')) does not match the type being destroyed ('A') in pseudo-destructor expression}}+ n.A::~T();
+ // expected-error@-1 {{the type of object expression ('T' (aka 'int')) does not match the type being destroyed ('A') in pseudo-destructor expression}}
n.A::T::~T(); n.A::T::~T();
- n.B::~T(); // expected-error {{'B' does not refer to a type name in pseudo-destructor expression}}+ n.B::~T();
+ // expected-error@-1 {{'B' does not refer to a type name in pseudo-destructor expression; expected the name of type 'T' (aka 'int')}}
n.B::T::~T(); n.B::T::~T();
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
- n.decltype(n)::~T(); // expected-error {{not a class, namespace, or enumeration}}+ n.decltype(n)::~T();
- n.T::~decltype(n)(); // expected-error {{expected a class name after '~'}}+ // since-cxx11-error@-1 {{'decltype(n)' (aka 'int') is not a class, namespace, or enumeration}}
+ n.T::~decltype(n)();
+ // since-cxx11-error@-1 {{expected a class name after '~' to name a destructor}}
n.~decltype(n)(); // OK n.~decltype(n)(); // OK
#endif #endif
} }
@@ -141,9 +153,9 @@ namespace dr1758 { // dr1758: 3.7
namespace dr1762 { // dr1762: 14 namespace dr1762 { // dr1762: 14
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
float operator ""_E(const char *); float operator ""_E(const char *);
- // expected-error@+2 {{invalid suffix on literal; C++11 requires a space between literal and identifier}}
- // expected-warning@+1 {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}}
float operator ""E(const char *); float operator ""E(const char *);
+ // since-cxx11-error@-1 {{invalid suffix on literal; C++11 requires a space between literal and identifier}}
+ // since-cxx11-warning@-2 {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}}
#endif #endif
} }
clang/test/CXX/drs/dr18xx.cpp
@@ -1,14 +1,14 @@
-// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected,cxx98 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify=expected,cxx11-17,since-cxx11 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,cxx11-17,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,cxx11-17,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx20,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx20,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx20,since-cxx11,since-cxx14 -fexceptions -Wno-deprecated-builtins -fcxx-exceptions -pedantic-errors
-+
-#if __cplusplus < 201103L+#if __cplusplus == 199711L
-// expected-error@+1 {{variadic macro}}
#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__) #define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
+// cxx98-error@-1 {{variadic macros are a C99 feature}}
#endif #endif
namespace dr1812 { // dr1812: no namespace dr1812 { // dr1812: no
@@ -16,7 +16,7 @@ namespace dr1812 { // dr1812: no
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
template <typename T> struct A { template <typename T> struct A {
using B = typename T::C<int>; using B = typename T::C<int>;
- // expected-error@-1 {{use 'template' keyword to treat 'C' as a dependent template name}}+ // since-cxx11-error@-1 {{use 'template' keyword to treat 'C' as a dependent template name}}
}; };
#endif #endif
} // namespace dr1812 } // namespace dr1812
@@ -54,15 +54,20 @@ namespace dr1814 { // dr1814: yes
namespace dr1815 { // dr1815: no namespace dr1815 { // dr1815: no
#if __cplusplus >= 201402L #if __cplusplus >= 201402L
// FIXME: needs codegen test // FIXME: needs codegen test
- struct A { int &&r = 0; }; // expected-note {{default member init}}+ struct A { int &&r = 0; }; // #dr1815-A
- A a = {}; // FIXME expected-warning {{not supported}}+ A a = {};
-+ // since-cxx14-warning@-1 {{sorry, lifetime extension of temporary created by aggregate initialization using default member initializer is not supported; lifetime of temporary will end at the end of the full-expression}} FIXME
- struct B { int &&r = 0; }; // expected-error {{binds to a temporary}} expected-note {{default member init}}+ // since-cxx14-note@#dr1815-A {{initializing field 'r' with default member initializer}}
- B b; // expected-note {{here}}+
+ struct B { int &&r = 0; }; // #dr1815-B
+ // since-cxx14-error@-1 {{reference member 'r' binds to a temporary object whose lifetime would be shorter than the lifetime of the constructed object}}
+ // since-cxx14-note@#dr1815-B {{initializing field 'r' with default member initializer}}
+ // since-cxx14-note@#dr1815-b {{in implicit default constructor for 'dr1815::B' first required here}}
+ B b; // #dr1815-b
#endif #endif
} }
-namespace dr1821 { // dr1821: yes+namespace dr1821 { // dr1821: 2.9
struct A { struct A {
template <typename> struct B { template <typename> struct B {
void f(); void f();
@@ -80,9 +85,9 @@ struct A {
namespace dr1822 { // dr1822: yes namespace dr1822 { // dr1822: yes
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
- int a;+ double a;
auto x = [] (int a) { auto x = [] (int a) {
-#pragma clang __debug dump a // CHECK: ParmVarDecl+ static_assert(__is_same(decltype(a), int), "should be resolved to lambda parameter");
}; };
#endif #endif
} }
@@ -98,16 +103,22 @@ namespace dr1837 { // dr1837: 3.3
}; };
class Outer { class Outer {
- friend auto Other::q() -> decltype(this->p()) *; // expected-error {{invalid use of 'this'}}+ friend auto Other::q() -> decltype(this->p()) *;
+ // since-cxx11-error@-1 {{invalid use of 'this' outside of a non-static member function}}
int g(); int g();
int f() { int f() {
extern void f(decltype(this->g()) *); extern void f(decltype(this->g()) *);
struct Inner { struct Inner {
- static_assert(Fish<decltype(this->g())>::value, ""); // expected-error {{invalid use of 'this'}}+ static_assert(Fish<decltype(this->g())>::value, "");
- enum { X = Fish<decltype(this->f())>::value }; // expected-error {{invalid use of 'this'}}+ // since-cxx11-error@-1 {{invalid use of 'this' outside of a non-static member function}}
- struct Inner2 : Fish<decltype(this->g())> { }; // expected-error {{invalid use of 'this'}}+ enum { X = Fish<decltype(this->f())>::value };
- friend void f(decltype(this->g()) *); // expected-error {{invalid use of 'this'}}+ // since-cxx11-error@-1 {{invalid use of 'this' outside of a non-static member function}}
- friend auto Other::q() -> decltype(this->p()) *; // expected-error {{invalid use of 'this'}}+ struct Inner2 : Fish<decltype(this->g())> { };
+ // since-cxx11-error@-1 {{invalid use of 'this' outside of a non-static member function}}
+ friend void f(decltype(this->g()) *);
+ // since-cxx11-error@-1 {{invalid use of 'this' outside of a non-static member function}}
+ friend auto Other::q() -> decltype(this->p()) *;
+ // since-cxx11-error@-1 {{invalid use of 'this' outside of a non-static member function}}
}; };
return 0; return 0;
} }
@@ -135,19 +146,21 @@ namespace dr1872 { // dr1872: 9
constexpr int x = A<X>().f(); constexpr int x = A<X>().f();
constexpr int y = A<Y>().f(); constexpr int y = A<Y>().f();
-#if __cplusplus <= 201703L+ // cxx11-17-error@-1 {{constexpr variable 'y' must be initialized by a constant expression}}
- // expected-error@-2 {{constant expression}} expected-note@-2 {{call to virtual function}}+ // cxx11-17-note@-2 {{cannot evaluate call to virtual function in a constant expression in C++ standards before C++20}}
-#else+#if __cplusplus >= 202002L
static_assert(y == 0); static_assert(y == 0);
#endif #endif
// Note, this is invalid even though it would not use virtual dispatch. // Note, this is invalid even though it would not use virtual dispatch.
constexpr int y2 = A<Y>().A<Y>::f(); constexpr int y2 = A<Y>().A<Y>::f();
-#if __cplusplus <= 201703L+ // cxx11-17-error@-1 {{constexpr variable 'y2' must be initialized by a constant expression}}
- // expected-error@-2 {{constant expression}} expected-note@-2 {{call to virtual function}}+ // cxx11-17-note@-2 {{cannot evaluate call to virtual function in a constant expression in C++ standards before C++20}}
-#else+#if __cplusplus >= 202002L
static_assert(y == 0); static_assert(y == 0);
#endif #endif
- constexpr int z = A<Z>().f(); // expected-error {{constant expression}} expected-note {{non-literal type}}+ constexpr int z = A<Z>().f();
+ // since-cxx11-error@-1 {{constexpr variable 'z' must be initialized by a constant expression}}
+ // since-cxx11-note@-2 {{non-literal type 'A<Z>' cannot be used in a constant expression}}
#endif #endif
} }
@@ -166,33 +179,38 @@ namespace dr1881 { // dr1881: 7
void dr1891() { // dr1891: 4 void dr1891() { // dr1891: 4
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
int n; int n;
- auto a = []{}; // expected-note 0-4{{}}+ auto a = []{}; // #dr1891-a
- auto b = [=]{ return n; }; // expected-note 0-4{{}}+ auto b = [=]{ return n; }; // #dr1891-b
typedef decltype(a) A; typedef decltype(a) A;
typedef decltype(b) B; typedef decltype(b) B;
static_assert(!__has_trivial_constructor(A), ""); static_assert(!__has_trivial_constructor(A), "");
-#if __cplusplus > 201703L+ // since-cxx20-error@-1 {{failed}}
- // expected-error@-2 {{failed}}
-#endif
static_assert(!__has_trivial_constructor(B), ""); static_assert(!__has_trivial_constructor(B), "");
// C++20 allows default construction for non-capturing lambdas (P0624R2). // C++20 allows default construction for non-capturing lambdas (P0624R2).
A x; A x;
-#if __cplusplus <= 201703L+ // cxx11-17-error@-1 {{no matching constructor for initialization of 'A' (aka '(lambda at}}
- // expected-error@-2 {{no matching constructor}}+ // cxx11-17-note@#dr1891-a {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided}}
-#endif+ // cxx11-17-note@#dr1891-a {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided}}
- B y; // expected-error {{no matching constructor}}+ B y;
+ // since-cxx11-error@-1 {{no matching constructor for initialization of 'B' (aka '(lambda at}}
+ // since-cxx11-note@#dr1891-b {{candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided}}
+ // since-cxx11-note@#dr1891-b {{candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided}}
// C++20 allows assignment for non-capturing lambdas (P0624R2). // C++20 allows assignment for non-capturing lambdas (P0624R2).
a = a; a = a;
+ // cxx11-17-error-re@-1 {{{{object of type '\(lambda at .+\)' cannot be assigned because its copy assignment operator is implicitly deleted}}}}
+ // cxx11-17-note@#dr1891-a {{lambda expression begins here}}
a = static_cast<A&&>(a); a = static_cast<A&&>(a);
-#if __cplusplus <= 201703L+ // cxx11-17-error-re@-1 {{{{object of type '\(lambda at .+\)' cannot be assigned because its copy assignment operator is implicitly deleted}}}}
- // expected-error@-3 {{copy assignment operator is implicitly deleted}}+ // cxx11-17-note@#dr1891-a {{lambda expression begins here}}
- // expected-error@-3 {{copy assignment operator is implicitly deleted}}+ b = b;
-#endif+ // since-cxx11-error-re@-1 {{{{object of type '\(lambda at .+\)' cannot be assigned because its copy assignment operator is implicitly deleted}}}}
- b = b; // expected-error {{copy assignment operator is implicitly deleted}}+ // since-cxx11-note@#dr1891-b {{lambda expression begins here}}
- b = static_cast<B&&>(b); // expected-error {{copy assignment operator is implicitly deleted}}+ b = static_cast<B&&>(b);
+ // since-cxx11-error-re@-1 {{{{object of type '\(lambda at .+\)' cannot be assigned because its copy assignment operator is implicitly deleted}}}}
+ // since-cxx11-note@#dr1891-b {{lambda expression begins here}}
#endif #endif
} }
clang/test/CXX/drs/dr19xx.cpp
@@ -1,41 +1,36 @@
-// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++98 %s -verify=expected,cxx98-11,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++11 %s -verify=expected,cxx98-11,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++14 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
namespace std { struct type_info; } namespace std { struct type_info; }
namespace dr1902 { // dr1902: 3.7 namespace dr1902 { // dr1902: 3.7
struct A {}; struct A {};
struct B { struct B {
- B(A);+ B(A); // #dr1902-B-A
-#if __cplusplus >= 201103L+ B() = delete; // #dr1902-B-ctor
- // expected-note@-2 {{candidate}}+ // cxx98-error@-1 {{deleted function definitions are a C++11 extension}}
-#endif+ B(const B&) = delete; // #dr1902-B-copy-ctor
-+ // cxx98-error@-1 {{deleted function definitions are a C++11 extension}}
- B() = delete;
-#if __cplusplus < 201103L
- // expected-error@-2 {{extension}}
-#endif
-
- B(const B&) // expected-note {{deleted here}}
-#if __cplusplus >= 201103L
- // expected-note@-2 {{candidate}}
-#else
- // expected-error@+2 {{extension}}
-#endif
- = delete;
-
operator A(); operator A();
}; };
extern B b1; extern B b1;
- B b2(b1); // expected-error {{call to deleted}}+ B b2(b1);
+ // expected-error@-1 {{call to deleted constructor of 'B'}}
+ // expected-note@#dr1902-B-copy-ctor {{'B' has been explicitly marked deleted here}}
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
// This is ambiguous, even though calling the B(const B&) constructor would // This is ambiguous, even though calling the B(const B&) constructor would
// both directly and indirectly call a deleted function. // both directly and indirectly call a deleted function.
- B b({}); // expected-error {{ambiguous}}+ B b({});
+ // since-cxx11-error@-1 {{call to constructor of 'B' is ambiguous}}
+ // since-cxx11-note@#dr1902-B-A {{candidate constructor}}
+ // since-cxx11-note@#dr1902-B-copy-ctor {{candidate constructor has been explicitly deleted}}
#endif #endif
} }
@@ -64,26 +59,33 @@ namespace dr1903 {
} }
} }
-namespace dr1909 { // dr1909: yes+namespace dr1909 { // dr1909: 3.7
struct A { struct A {
- template<typename T> struct A {}; // expected-error {{member 'A' has the same name as its class}}+ template<typename T> struct A {};
+ // expected-error@-1 {{member 'A' has the same name as its class}}
}; };
struct B { struct B {
- template<typename T> void B() {} // expected-error {{constructor cannot have a return type}}+ template<typename T> void B() {}
+ // expected-error@-1 {{constructor cannot have a return type}}
}; };
struct C { struct C {
- template<typename T> static int C; // expected-error {{member 'C' has the same name as its class}} expected-error 0-1{{extension}}+ template<typename T> static int C;
+ // expected-error@-1 {{member 'C' has the same name as its class}}
+ // cxx98-11-error@-2 {{variable templates are a C++14 extension}}
}; };
struct D { struct D {
- template<typename T> using D = int; // expected-error {{member 'D' has the same name as its class}} expected-error 0-1{{extension}}+ template<typename T> using D = int;
+ // cxx98-error@-1 {{alias declarations are a C++11 extension}}
+ // expected-error@-2 {{member 'D' has the same name as its class}}
}; };
} }
-namespace dr1940 { // dr1940: yes+namespace dr1940 { // dr1940: 3.5
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
static union { static union {
static_assert(true, ""); // ok static_assert(true, ""); // ok
- static_assert(false, ""); // expected-error {{static assertion failed}}+ static_assert(false, "");
+ // since-cxx11-error@-1 {{static assertion failed}}
int not_empty; int not_empty;
}; };
#endif #endif
@@ -119,18 +121,21 @@ derived d2(42, 9);
#endif #endif
} }
-namespace dr1947 { // dr1947: yes+namespace dr1947 { // dr1947: 3.5
#if __cplusplus >= 201402L #if __cplusplus >= 201402L
unsigned o = 0'01; // ok unsigned o = 0'01; // ok
-unsigned b = 0b'01; // expected-error {{invalid digit 'b' in octal constant}}+unsigned b = 0b'01;
-unsigned x = 0x'01; // expected-error {{invalid suffix 'x'01' on integer constant}}+// since-cxx14-error@-1 {{invalid digit 'b' in octal constant}}
+unsigned x = 0x'01;
+// since-cxx14-error@-1 {{invalid suffix 'x'01' on integer constant}}
#endif #endif
} }
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
-// dr1948: yes+// dr1948: 3.5
// FIXME: This diagnostic could be improved. // FIXME: This diagnostic could be improved.
-void *operator new(__SIZE_TYPE__) noexcept { return nullptr; } // expected-error{{exception specification in declaration does not match previous declaration}}+void *operator new(__SIZE_TYPE__) noexcept { return nullptr; }
+// since-cxx11-error@-1 {{exception specification in declaration does not match previous declaration}}
#endif #endif
namespace dr1959 { // dr1959: 3.9 namespace dr1959 { // dr1959: 3.9
@@ -139,22 +144,31 @@ namespace dr1959 { // dr1959: 3.9
struct c; struct c;
struct a { struct a {
a() = default; a() = default;
- a(const a &) = delete; // expected-note {{deleted}}+ a(const a &) = delete; // #dr1959-copy-ctor
a(const b &) = delete; // not inherited a(const b &) = delete; // not inherited
- a(c &&) = delete; // expected-note {{not viable}}+ a(c &&) = delete; // #dr1959-move-ctor
- template<typename T> a(T) = delete; // expected-note {{would take its own class type by value}}+ template<typename T> a(T) = delete; // #dr1959-temp-ctor
}; };
- struct b : a { // expected-note {{cannot bind}} expected-note {{deleted because}}+ struct b : a { // #dr1959-b
- using a::a; // expected-note 2{{inherited here}}+ using a::a; // #dr1959-using-a
}; };
a x; a x;
// FIXME: As a resolution to an open DR against P0136R0, we disallow // FIXME: As a resolution to an open DR against P0136R0, we disallow
// use of inherited constructors to construct from a single argument // use of inherited constructors to construct from a single argument
// where the base class is reference-related to the argument type. // where the base class is reference-related to the argument type.
- b y = x; // expected-error {{no viable conversion}}+ b y = x;
- b z = z; // expected-error {{deleted}}+ // since-cxx11-error@-1 {{no viable conversion from 'a' to 'b'}}
+ // since-cxx11-note@#dr1959-move-ctor {{candidate inherited constructor not viable: no known conversion from 'a' to 'c &&' for 1st argument}}
+ // since-cxx11-note@#dr1959-using-a {{constructor from base class 'a' inherited here}}
+ // since-cxx11-note@#dr1959-b {{candidate constructor (the implicit copy constructor) not viable: cannot bind base class object of type 'a' to derived class reference 'const b &' for 1st argument}}
+ // since-cxx11-note@#dr1959-temp-ctor {{candidate template ignored: instantiation would take its own class type by value}}
+ // since-cxx11-note@#dr1959-using-a {{constructor from base class 'a' inherited here}}
+ b z = z;
+ // since-cxx11-error@-1 {{call to implicitly-deleted copy constructor of 'b'}}
+ // since-cxx11-note@#dr1959-b {{copy constructor of 'b' is implicitly deleted because base class 'a' has a deleted copy constructor}}
+ // since-cxx11-note@#dr1959-copy-ctor {{'a' has been explicitly marked deleted here}}
struct c : a { struct c : a {
using a::a; using a::a;
@@ -191,16 +205,28 @@ using A::g;
namespace dr1966 { // dr1966: 11 namespace dr1966 { // dr1966: 11
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
struct A { struct A {
- enum E : int {1}; // expected-error {{expected identifier}} (not bit-field)+ enum E : int {1};
+ // since-cxx11-error@-1 {{expected identifier}} (not bit-field)
}; };
- auto *p1 = new enum E : int; // expected-error {{only permitted as a standalone declaration}}+ auto *p1 = new enum E : int;
- auto *p2 = new enum F : int {}; // expected-error {{only permitted as a standalone declaration}}+ // since-cxx11-error@-1 {{non-defining declaration of enumeration with a fixed underlying type is only permitted as a standalone declaration}}
- auto *p3 = true ? new enum G : int {}; // expected-error {{forward reference}} expected-error {{incomplete}} expected-note {{declaration}}+ auto *p2 = new enum F : int {};
- auto h() -> enum E : int {}; // expected-error {{only permitted as a standalone declaration}}+ // since-cxx11-error@-1 {{non-defining declaration of enumeration with a fixed underlying type is only permitted as a standalone declaration}}
-+ auto *p3 = true ? new enum G : int {};
- enum X : enum Y : int {} {}; // expected-error {{cannot be defined in a type specifier}}+ // since-cxx11-error@-1 {{ISO C++ forbids forward references to 'enum' types}}
+ // since-cxx11-error@-2 {{allocation of incomplete type 'enum G'}}
+ // since-cxx11-note@-3 {{forward declaration of 'dr1966::G'}}
+ auto h() -> enum E : int {};
+ // since-cxx11-error@-1 {{non-defining declaration of enumeration with a fixed underlying type is only permitted as a standalone declaration}}
+
+ enum X : enum Y : int {} {};
+ // since-cxx11-error@-1 {{'dr1966::Y' cannot be defined in a type specifier}}
struct Q { struct Q {
- enum X : enum Y : int {} {}; // expected-error +{{}}+ // FIXME: can we emit something nicer than that?
+ enum X : enum Y : int {} {};
+ // since-cxx11-error@-1 {{non-defining declaration of enumeration with a fixed underlying type is only permitted as a standalone declaration; missing list of enumerators?}}
+ // since-cxx11-error@-2 {{non-integral type 'enum Y' is an invalid underlying type}}
+ // since-cxx11-error@-3 {{anonymous bit-field cannot have a default member initializer}}
}; };
#endif #endif
} }
clang/test/CXX/drs/dr25xx.cpp
@@ -10,7 +10,7 @@
// expected-no-diagnostics // expected-no-diagnostics
#endif #endif
-namespace dr2516 { // dr2516: yes+namespace dr2516 { // dr2516: 3.0
// NB: reusing 1482 test // NB: reusing 1482 test
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
template <typename T> struct S { template <typename T> struct S {
clang/test/CXX/drs/dr412.cpp
@@ -1,9 +1,12 @@
// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT="throw()" -DBAD_ALLOC="throw(std::bad_alloc)" // RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT="throw()" -DBAD_ALLOC="throw(std::bad_alloc)"
// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT=noexcept -DBAD_ALLOC= // RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT=noexcept -DBAD_ALLOC=
// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT=noexcept -DBAD_ALLOC= // RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT=noexcept -DBAD_ALLOC=
-// RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT=noexcept -DBAD_ALLOC=+// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT=noexcept -DBAD_ALLOC=
+// RUN: %clang_cc1 -std=c++20 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT=noexcept -DBAD_ALLOC=
+// RUN: %clang_cc1 -std=c++23 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT=noexcept -DBAD_ALLOC=
+// RUN: %clang_cc1 -std=c++2c %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -DNOEXCEPT=noexcept -DBAD_ALLOC=
-// dr412: yes+// dr412: 3.4
// lwg404: yes // lwg404: yes
// lwg2340: yes // lwg2340: yes
@@ -11,11 +14,17 @@
__extension__ typedef __SIZE_TYPE__ size_t; __extension__ typedef __SIZE_TYPE__ size_t;
namespace std { struct bad_alloc {}; } namespace std { struct bad_alloc {}; }
-inline void* operator new(size_t) BAD_ALLOC; // expected-error {{cannot be declared 'inline'}}+inline void* operator new(size_t) BAD_ALLOC;
-inline void* operator new[](size_t) BAD_ALLOC; // expected-error {{cannot be declared 'inline'}}+// expected-error@-1 {{replacement function 'operator new' cannot be declared 'inline'}}
-inline void operator delete(void*) NOEXCEPT; // expected-error {{cannot be declared 'inline'}}+inline void* operator new[](size_t) BAD_ALLOC;
-inline void operator delete[](void*) NOEXCEPT; // expected-error {{cannot be declared 'inline'}}+// expected-error@-1 {{replacement function 'operator new[]' cannot be declared 'inline'}}
+inline void operator delete(void*) NOEXCEPT;
+// expected-error@-1 {{replacement function 'operator delete' cannot be declared 'inline'}}
+inline void operator delete[](void*) NOEXCEPT;
+// expected-error@-1 {{replacement function 'operator delete[]' cannot be declared 'inline'}}
#ifdef __cpp_sized_deallocation #ifdef __cpp_sized_deallocation
-inline void operator delete(void*, size_t) NOEXCEPT; // expected-error {{cannot be declared 'inline'}}+inline void operator delete(void*, size_t) NOEXCEPT;
-inline void operator delete[](void*, size_t) NOEXCEPT; // expected-error {{cannot be declared 'inline'}}+// expected-error@-1 {{replacement function 'operator delete' cannot be declared 'inline'}}
+inline void operator delete[](void*, size_t) NOEXCEPT;
+// expected-error@-1 {{replacement function 'operator delete[]' cannot be declared 'inline'}}
#endif #endif
clang/test/CXX/drs/dr7xx.cpp
@@ -1,37 +1,53 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++98 %s -verify=expected,cxx98-14,cxx98-11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 %s -verify=expected,cxx98-14,cxx98-11,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++14 %s -verify=expected,cxx98-14,since-cxx14,since-cxx11,cxx14 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++17 %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++2a %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++2a %s -verify=expected,since-cxx14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
namespace dr705 { // dr705: yes namespace dr705 { // dr705: yes
namespace N { namespace N {
struct S {}; struct S {};
- void f(S); // expected-note {{declared here}}+ void f(S); // #dr705-f
} }
void g() { void g() {
N::S s; N::S s;
f(s); // ok f(s); // ok
- (f)(s); // expected-error {{use of undeclared}}+ (f)(s);
+ // expected-error@-1 {{use of undeclared identifier 'f'}}
+ // expected-note@#dr705-f {{'N::f' declared here}}
} }
} }
namespace dr712 { // dr712: partial namespace dr712 { // dr712: partial
void use(int); void use(int);
void f() { void f() {
- const int a = 0; // expected-note 5{{here}}+ const int a = 0; // #dr712-f-a
struct X { struct X {
void g(bool cond) { void g(bool cond) {
use(a); use(a);
use((a)); use((a));
use(cond ? a : a); use(cond ? a : a);
- use((cond, a)); // expected-warning 2{{left operand of comma operator has no effect}} FIXME: should only warn once+ // FIXME: should only warn once
-+ use((cond, a));
- (void)a; // FIXME: expected-error {{declared in enclosing}}+ // expected-warning@-1 {{left operand of comma operator has no effect}}
- (void)(a); // FIXME: expected-error {{declared in enclosing}}+ // expected-warning@-2 {{left operand of comma operator has no effect}}
- (void)(cond ? a : a); // FIXME: expected-error 2{{declared in enclosing}}+
- (void)(cond, a); // FIXME: expected-error {{declared in enclosing}} expected-warning {{left operand of comma operator has no effect}}+ (void)a;
+ // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'dr712::f'}} FIXME
+ // expected-note@#dr712-f-a {{'a' declared here}}
+ (void)(a);
+ // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'dr712::f'}} FIXME
+ // expected-note@#dr712-f-a {{'a' declared here}}
+ (void)(cond ? a : a); // #dr712-ternary
+ // expected-error@#dr712-ternary {{reference to local variable 'a' declared in enclosing function 'dr712::f'}} FIXME
+ // expected-note@#dr712-f-a {{'a' declared here}}
+ // expected-error@#dr712-ternary {{reference to local variable 'a' declared in enclosing function 'dr712::f'}} FIXME
+ // expected-note@#dr712-f-a {{'a' declared here}}
+ (void)(cond, a); // #dr712-comma
+ // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'dr712::f'}} FIXME
+ // expected-note@#dr712-f-a {{'a' declared here}}
+ // expected-warning@#dr712-comma {{left operand of comma operator has no effect}}
} }
}; };
} }
@@ -39,14 +55,18 @@ namespace dr712 { // dr712: partial
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
void g() { void g() {
struct A { int n; }; struct A { int n; };
- constexpr A a = {0}; // expected-note 2{{here}}+ constexpr A a = {0}; // #dr712-g-a
struct X { struct X {
void g(bool cond) { void g(bool cond) {
use(a.n); use(a.n);
use(a.*&A::n); use(a.*&A::n);
- (void)a.n; // FIXME: expected-error {{declared in enclosing}}+ (void)a.n;
- (void)(a.*&A::n); // FIXME: expected-error {{declared in enclosing}}+ // since-cxx11-error@-1 {{reference to local variable 'a' declared in enclosing function 'dr712::g'}} FIXME
+ // since-cxx11-note@#dr712-g-a {{'a' declared here}}
+ (void)(a.*&A::n);
+ // since-cxx11-error@-1 {{reference to local variable 'a' declared in enclosing function 'dr712::g'}} FIXME
+ // since-cxx11-note@#dr712-g-a {{'a' declared here}}
} }
}; };
} }
@@ -55,9 +75,10 @@ namespace dr712 { // dr712: partial
namespace dr727 { // dr727: partial namespace dr727 { // dr727: partial
struct A { struct A {
- template<typename T> struct C; // expected-note 6{{here}}+ template<typename T> struct C; // #dr727-C
- template<typename T> void f(); // expected-note {{here}}+ template<typename T> void f(); // #dr727-f
- template<typename T> static int N; // expected-error 0-1{{C++14}} expected-note 6{{here}}+ template<typename T> static int N; // #dr727-N
+ // cxx98-11-error@-1 {{variable templates are a C++14 extension}}
template<> struct C<int>; template<> struct C<int>;
template<> void f<int>(); template<> void f<int>();
@@ -67,19 +88,40 @@ namespace dr727 { // dr727: partial
template<typename T> static int N<T*>; template<typename T> static int N<T*>;
struct B { struct B {
- template<> struct C<float>; // expected-error {{not in class 'A' or an enclosing namespace}}+ template<> struct C<float>;
- template<> void f<float>(); // expected-error {{no function template matches}}+ // expected-error@-1 {{class template specialization of 'C' not in class 'A' or an enclosing namespace}}
- template<> static int N<float>; // expected-error {{not in class 'A' or an enclosing namespace}}+ // expected-note@#dr727-C {{explicitly specialized declaration is here}}
-+ template<> void f<float>();
- template<typename T> struct C<T**>; // expected-error {{not in class 'A' or an enclosing namespace}}+ // expected-error@-1 {{no function template matches function template specialization 'f'}}
- template<typename T> static int N<T**>; // expected-error {{not in class 'A' or an enclosing namespace}}+ template<> static int N<float>;
-+ // expected-error@-1 {{variable template specialization of 'N' not in class 'A' or an enclosing namespace}}
- template<> struct A::C<double>; // expected-error {{not in class 'A' or an enclosing namespace}}+ // expected-note@#dr727-N {{explicitly specialized declaration is here}}
- template<> void A::f<double>(); // expected-error {{no function template matches}} expected-error {{cannot have a qualified name}}+
- template<> static int A::N<double>; // expected-error {{not in class 'A' or an enclosing namespace}} expected-error {{cannot have a qualified name}}+ template<typename T> struct C<T**>;
-+ // expected-error@-1 {{class template partial specialization of 'C' not in class 'A' or an enclosing namespace}}
- template<typename T> struct A::C<T***>; // expected-error {{not in class 'A' or an enclosing namespace}}+ // expected-note@#dr727-C {{explicitly specialized declaration is here}}
- template<typename T> static int A::N<T***>; // expected-error {{not in class 'A' or an enclosing namespace}} expected-error {{cannot have a qualified name}}+ template<typename T> static int N<T**>;
+ // expected-error@-1 {{variable template partial specialization of 'N' not in class 'A' or an enclosing namespace}}
+ // expected-note@#dr727-N {{explicitly specialized declaration is here}}
+
+ template<> struct A::C<double>;
+ // expected-error@-1 {{class template specialization of 'C' not in class 'A' or an enclosing namespace}}
+ // expected-note@#dr727-C {{explicitly specialized declaration is here}}
+ template<> void A::f<double>();
+ // expected-error@-1 {{o function template matches function template specialization 'f'}}
+ // expected-error@-2 {{non-friend class member 'f' cannot have a qualified name}}
+ template<> static int A::N<double>;
+ // expected-error@-1 {{non-friend class member 'N' cannot have a qualified name}}
+ // expected-error@-2 {{variable template specialization of 'N' not in class 'A' or an enclosing namespace}}
+ // expected-note@#dr727-N {{explicitly specialized declaration is here}}
+
+ template<typename T> struct A::C<T***>;
+ // expected-error@-1 {{class template partial specialization of 'C' not in class 'A' or an enclosing namespace}}
+ // expected-note@#dr727-C {{explicitly specialized declaration is here}}
+ template<typename T> static int A::N<T***>;
+ // expected-error@-1 {{non-friend class member 'N' cannot have a qualified name}}
+ // expected-error@-2 {{variable template partial specialization of 'N' not in class 'A' or an enclosing namespace}}
+ // expected-note@#dr727-N {{explicitly specialized declaration is here}}
}; };
}; };
@@ -91,19 +133,36 @@ namespace dr727 { // dr727: partial
template<typename T> int A::N<T****>; template<typename T> int A::N<T****>;
namespace C { namespace C {
- template<> struct A::C<long>; // expected-error {{not in class 'A' or an enclosing namespace}}+ template<> struct A::C<long>;
- template<> void A::f<long>(); // expected-error {{not in class 'A' or an enclosing namespace}}+ // expected-error@-1 {{class template specialization of 'C' not in class 'A' or an enclosing namespace}}
- template<> int A::N<long>; // expected-error {{not in class 'A' or an enclosing namespace}}+ // expected-note@#dr727-C {{explicitly specialized declaration is here}}
-+ template<> void A::f<long>();
- template<typename T> struct A::C<T*****>; // expected-error {{not in class 'A' or an enclosing namespace}}+ // expected-error@-1 {{function template specialization of 'f' not in class 'A' or an enclosing namespace}}
- template<typename T> int A::N<T*****>; // expected-error {{not in class 'A' or an enclosing namespace}}+ // expected-note@#dr727-f {{explicitly specialized declaration is here}}
+ template<> int A::N<long>;
+ // expected-error@-1 {{variable template specialization of 'N' not in class 'A' or an enclosing namespace}}
+ // expected-note@#dr727-N {{explicitly specialized declaration is here}}
+
+ template<typename T> struct A::C<T*****>;
+ // expected-error@-1 {{class template partial specialization of 'C' not in class 'A' or an enclosing namespace}}
+ // expected-note@#dr727-C {{explicitly specialized declaration is here}}
+ template<typename T> int A::N<T*****>;
+ // expected-error@-1 {{variable template partial specialization of 'N' not in class 'A' or an enclosing namespace}}
+ // expected-note@#dr727-N {{explicitly specialized declaration is here}}
} }
template<typename> template<typename>
struct D { struct D {
- template<typename T> struct C { typename T::error e; }; // expected-error {{no members}}+ template<typename T> struct C { typename T::error e; };
- template<typename T> void f() { T::error; } // expected-error {{no members}}+ // expected-error@-1 {{type 'float' cannot be used prior to '::' because it has no members}}
- template<typename T> static const int N = T::error; // expected-error {{no members}} expected-error 0-1{{C++14}}+ // expected-note@#dr727-C-float {{in instantiation of template class 'dr727::D<int>::C<float>' requested here}}
+ template<typename T> void f() { T::error; }
+ // expected-error@-1 {{type 'float' cannot be used prior to '::' because it has no members}}
+ // expected-note@#dr727-f-float {{in instantiation of function template specialization 'dr727::D<int>::f<float>' requested here}}
+ template<typename T> static const int N = T::error;
+ // cxx98-11-error@-1 {{variable templates are a C++14 extension}}
+ // expected-error@-2 {{type 'float' cannot be used prior to '::' because it has no members}}
+ // expected-note@#dr727-N-float {{in instantiation of static data member 'dr727::D<int>::N<float>' requested here}}
template<> struct C<int> {}; template<> struct C<int> {};
template<> void f<int>() {} template<> void f<int>() {}
@@ -114,7 +173,8 @@ namespace dr727 { // dr727: partial
template<typename> template<typename>
struct E { struct E {
- template<> void f<void>() {} // expected-error {{no candidate function template}}+ template<> void f<void>() {}
+ // expected-error@-1 {{no candidate function template was found for dependent member function template specialization}}
}; };
}; };
@@ -126,9 +186,9 @@ namespace dr727 { // dr727: partial
D<int>::C<int*>(); D<int>::C<int*>();
int b = D<int>::N<int*>; int b = D<int>::N<int*>;
- D<int>::C<float>(); // expected-note {{instantiation of}}+ D<int>::C<float>(); // #dr727-C-float
- di.f<float>(); // expected-note {{instantiation of}}+ di.f<float>(); // #dr727-f-float
- int c = D<int>::N<float>; // expected-note {{instantiation of}}+ int c = D<int>::N<float>; // #dr727-N-float
} }
namespace mixed_inner_outer_specialization { namespace mixed_inner_outer_specialization {
@@ -148,28 +208,30 @@ namespace dr727 { // dr727: partial
#if __cplusplus >= 201402L #if __cplusplus >= 201402L
template<int> struct B { template<int> struct B {
template<int> static const int u = 1; template<int> static const int u = 1;
- template<> static const int u<0> = 2; // expected-note {{here}}+ template<> static const int u<0> = 2; // #dr727-u0
// Note that in C++17 onwards, these are implicitly inline, and so the // Note that in C++17 onwards, these are implicitly inline, and so the
// initializer of v<0> is not instantiated with the declaration. In // initializer of v<0> is not instantiated with the declaration. In
// C++14, v<0> is a non-defining declaration and its initializer is // C++14, v<0> is a non-defining declaration and its initializer is
// instantiated with the class. // instantiated with the class.
template<int> static constexpr int v = 1; template<int> static constexpr int v = 1;
- template<> static constexpr int v<0> = 2; // #v0+ template<> static constexpr int v<0> = 2; // #dr727-v0
- template<int> static const inline int w = 1; // expected-error 0-1{{C++17 extension}}+ template<int> static const inline int w = 1;
- template<> static const inline int w<0> = 2; // expected-error 0-1{{C++17 extension}}+ // cxx14-error@-1 {{inline variables are a C++17 extension}}
+ template<> static const inline int w<0> = 2;
+ // cxx14-error@-1 {{inline variables are a C++17 extension}}
}; };
template<> template<int> constexpr int B<0>::u = 3; template<> template<int> constexpr int B<0>::u = 3;
- template<> template<> constexpr int B<0>::u<0> = 4; // expected-error {{already has an initializer}}+ template<> template<> constexpr int B<0>::u<0> = 4;
+ // since-cxx14-error@-1 {{static data member 'u' already has an initializer}}
+ // since-cxx14-note@#dr727-u0 {{previous initialization is here}}
template<> template<int> constexpr int B<0>::v = 3; template<> template<int> constexpr int B<0>::v = 3;
template<> template<> constexpr int B<0>::v<0> = 4; template<> template<> constexpr int B<0>::v<0> = 4;
-#if __cplusplus < 201702L+ // cxx14-error@-1 {{static data member 'v' already has an initializer}}
- // expected-error@-2 {{already has an initializer}}+ // cxx14-note@#dr727-v0 {{previous initialization is here}}
- // expected-note@#v0 {{here}}
-#endif
template<> template<int> constexpr int B<0>::w = 3; template<> template<int> constexpr int B<0>::w = 3;
template<> template<> constexpr int B<0>::w<0> = 4; template<> template<> constexpr int B<0>::w<0> = 4;
@@ -182,10 +244,8 @@ namespace dr727 { // dr727: partial
static_assert(B<1>().v<0> == 2, ""); static_assert(B<1>().v<0> == 2, "");
static_assert(B<0>().v<1> == 3, ""); static_assert(B<0>().v<1> == 3, "");
static_assert(B<0>().v<0> == 4, ""); static_assert(B<0>().v<0> == 4, "");
-#if __cplusplus < 201702L+ // cxx14-error@-1 {{static assertion failed due to requirement 'dr727::mixed_inner_outer_specialization::B<0>().v<0> == 4'}}
- // expected-error@-2 {{failed}} \+ // cxx14-note@-2 {{expression evaluates to '2 == 4'}}
- // expected-note@-2 {{evaluates to '2 == 4'}}
-#endif
static_assert(B<1>().w<1> == 1, ""); static_assert(B<1>().w<1> == 1, "");
static_assert(B<1>().w<0> == 2, ""); static_assert(B<1>().w<0> == 2, "");
@@ -205,13 +265,23 @@ namespace dr727 { // dr727: partial
template<> int f2<T>() {} template<> int f2<T>() {}
template<> int f2<U>() {} template<> int f2<U>() {}
- template<typename> static int v1; // expected-error 0-1{{C++14 extension}}+ template<typename> static int v1;
- template<> static int v1<T>; // expected-note {{previous}}+ // cxx98-11-error@-1 {{variable templates are a C++14 extension}}
- template<> static int v1<U>; // expected-error {{duplicate member}}+ template<> static int v1<T>; // #dr727-v1-T
-+ template<> static int v1<U>;
- template<typename> static inline int v2; // expected-error 0-1{{C++17 extension}} expected-error 0-1{{C++14 extension}}+ // expected-error@-1 {{duplicate member 'v1'}}
- template<> static inline int v2<T>; // expected-error 0-1{{C++17 extension}} expected-note {{previous}}+ // expected-note@#dr727-Collision-int-int {{in instantiation of template class 'dr727::Collision<int, int>' requested here}}
- template<> static inline int v2<U>; // expected-error 0-1{{C++17 extension}} expected-error {{duplicate member}}+ // expected-note@#dr727-v1-T {{previous}}
+
+ template<typename> static inline int v2;
+ // cxx98-11-error@-1 {{variable templates are a C++14 extension}}
+ // cxx98-14-error@-2 {{inline variables are a C++17 extension}}
+ template<> static inline int v2<T>; // #dr727-v2-T
+ // cxx98-14-error@-1 {{inline variables are a C++17 extension}}
+ template<> static inline int v2<U>;
+ // cxx98-14-error@-1 {{inline variables are a C++17 extension}}
+ // expected-error@-2 {{duplicate member 'v2'}}
+ // expected-note@#dr727-v2-T {{previous declaration is here}}
// FIXME: Missing diagnostic for duplicate class explicit specialization. // FIXME: Missing diagnostic for duplicate class explicit specialization.
template<typename> struct S1; template<typename> struct S1;
@@ -219,10 +289,12 @@ namespace dr727 { // dr727: partial
template<> struct S1<U>; template<> struct S1<U>;
template<typename> struct S2; template<typename> struct S2;
- template<> struct S2<T> {}; // expected-note {{previous}}+ template<> struct S2<T> {}; // #dr727-S2-T
- template<> struct S2<U> {}; // expected-error {{redefinition}}+ template<> struct S2<U> {};
+ // expected-error@-1 {{redefinition of 'S2<int>'}}
+ // expected-note@#dr727-S2-T {{previous}}
}; };
- Collision<int, int> c; // expected-note {{in instantiation of}}+ Collision<int, int> c; // #dr727-Collision-int-int
} }
namespace dr777 { // dr777: 3.7 namespace dr777 { // dr777: 3.7
clang/test/CXX/drs/dr8xx.cpp
@@ -1,30 +1,27 @@
-// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s+// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s+// RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors 2>&1 | FileCheck %s+// RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
+#if __cplusplus == 199711L
// expected-no-diagnostics // expected-no-diagnostics
+#endif
-namespace dr873 { // dr873: yes+namespace dr873 { // dr873: 3.0
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
template <typename T> void f(T &&); template <typename T> void f(T &&);
-template <> void f(int &) {} // #1+template <> void f(int &) = delete; // #dr873-lvalue-ref
-template <> void f(int &&) {} // #2+template <> void f(int &&) = delete; // #dr873-rvalue-ref
void g(int i) { void g(int i) {
- f(i); // calls f<int&>(int&), i.e., #1+ f(i); // calls f<int&>(int&)
-#pragma clang __debug dump f(i)+ // since-cxx11-error@-1 {{call to deleted function 'f'}}
- // CHECK: CallExpr {{.*}}+ // since-cxx11-note@#dr873-lvalue-ref {{candidate function [with T = int &] has been implicitly deleted}}
- // CHECK-NEXT: |-ImplicitCastExpr {{.*}}+ f(0); // calls f<int>(int&&)
- // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'f' 'void (int &)' {{.*}}+ // since-cxx11-error@-1 {{call to deleted function 'f'}}
-+ // since-cxx11-note@#dr873-rvalue-ref {{candidate function [with T = int] has been implicitly deleted}}
- f(0); // calls f<int>(int&&), i.e., #2
-#pragma clang __debug dump f(0)
- // CHECK: CallExpr {{.*}}
- // CHECK-NEXT: |-ImplicitCastExpr {{.*}}
- // CHECK-NEXT: | `-DeclRefExpr {{.*}} 'f' 'void (int &&)' {{.*}}
} }
#endif #endif
} // namespace dr873 } // namespace dr873
clang/test/CXX/drs/dr9xx.cpp
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++98 %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++11 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++14 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++20 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
-// RUN: %clang_cc1 -std=c++23 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors+// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
namespace std { namespace std {
__extension__ typedef __SIZE_TYPE__ size_t; __extension__ typedef __SIZE_TYPE__ size_t;
@@ -43,30 +43,34 @@ namespace dr948 { // dr948: 3.7
#endif #endif
} }
-namespace dr952 { // dr952: yes+namespace dr952 { // dr952: 2.8
namespace example1 { namespace example1 {
struct A { struct A {
- typedef int I; // #dr952-typedef-decl+ typedef int I; // #dr952-I
}; };
-struct B : private A { // #dr952-inheritance+struct B : private A { // #dr952-B
}; };
struct C : B { struct C : B {
void f() { void f() {
- I i1; // expected-error {{private member}}+ I i1;
- // expected-note@#dr952-inheritance {{constrained by private inheritance}}+ // expected-error@-1 {{'I' is a private member of 'dr952::example1::A'}}
- // expected-note@#dr952-typedef-decl {{declared here}}+ // expected-note@#dr952-B {{constrained by private inheritance here}}
+ // expected-note@#dr952-I {{member is declared here}}
} }
- I i2; // expected-error {{private member}}+ I i2;
- // expected-note@#dr952-inheritance {{constrained by private inheritance}}+ // expected-error@-1 {{'I' is a private member of 'dr952::example1::A'}}
- // expected-note@#dr952-typedef-decl {{declared here}}+ // expected-note@#dr952-B {{constrained by private inheritance here}}
+ // expected-note@#dr952-I {{member is declared here}}
struct D { struct D {
- I i3; // expected-error {{private member}}+ I i3;
- // expected-note@#dr952-inheritance {{constrained by private inheritance}}+ // expected-error@-1 {{'I' is a private member of 'dr952::example1::A'}}
- // expected-note@#dr952-typedef-decl {{declared here}}+ // expected-note@#dr952-B {{constrained by private inheritance here}}
+ // expected-note@#dr952-I {{member is declared here}}
void g() { void g() {
- I i4; // expected-error {{private member}}+ I i4;
- // expected-note@#dr952-inheritance {{constrained by private inheritance}}+ // expected-error@-1 {{'I' is a private member of 'dr952::example1::A'}}
- // expected-note@#dr952-typedef-decl {{declared here}}+ // expected-note@#dr952-B {{constrained by private inheritance here}}
+ // expected-note@#dr952-I {{member is declared here}}
} }
}; };
}; };
@@ -91,10 +95,10 @@ namespace dr974 { // dr974: yes
} }
namespace dr977 { // dr977: yes namespace dr977 { // dr977: yes
-enum E { e = E() };+enum E { e = E() }; // #dr977-E
#if !defined(_WIN32) || defined(__MINGW32__) #if !defined(_WIN32) || defined(__MINGW32__)
-// expected-error@-2 {{invalid use of incomplete type 'E'}}+// expected-error@#dr977-E {{invalid use of incomplete type 'E'}}
-// expected-note@-3 {{definition of 'dr977::E' is not complete until the closing '}'}}+// expected-note@#dr977-E {{definition of 'dr977::E' is not complete until the closing '}'}}
#endif #endif
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
enum E2 : int { e2 = E2() }; enum E2 : int { e2 = E2() };
@@ -105,23 +109,29 @@ enum struct E4 : int { e = static_cast<int>(E4()) };
namespace dr990 { // dr990: 3.5 namespace dr990 { // dr990: 3.5
#if __cplusplus >= 201103L #if __cplusplus >= 201103L
- struct A { // expected-note 2{{candidate}}+ struct A { // #dr990-A
- A(std::initializer_list<int>); // expected-note {{candidate}}+ A(std::initializer_list<int>); // #dr990-A-init-list
}; };
struct B { struct B {
A a; A a;
}; };
B b1 { }; B b1 { };
- B b2 { 1 }; // expected-error {{no viable conversion from 'int' to 'A'}}+ B b2 { 1 };
+ // since-cxx11-error@-1 {{no viable conversion from 'int' to 'A'}}
+ // since-cxx11-note@#dr990-A {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const A &' for 1st argument}}
+ // since-cxx11-note@#dr990-A {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to 'A &&' for 1st argument}}
+ // since-cxx11-note@#dr990-A-init-list {{candidate constructor not viable: no known conversion from 'int' to 'std::initializer_list<int>' for 1st argument}}
B b3 { { 1 } }; B b3 { { 1 } };
struct C { struct C {
C(); C();
C(int); C(int);
- C(std::initializer_list<int>) = delete; // expected-note {{here}}+ C(std::initializer_list<int>) = delete; // #dr990-deleted
}; };
C c1[3] { 1 }; // ok C c1[3] { 1 }; // ok
- C c2[3] { 1, {2} }; // expected-error {{call to deleted}}+ C c2[3] { 1, {2} };
+ // since-cxx11-error@-1 {{call to deleted constructor of 'C'}}
+ // since-cxx11-note@#dr990-deleted {{'C' has been explicitly marked deleted here}}
struct D { struct D {
D(); D();
clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_reinterpret_svcount_svbool.c
@@ -0,0 +1,47 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+
+// REQUIRES: aarch64-registered-target
+
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme2 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme2 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme2 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme2 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK
+
+#include <arm_sme_draft_spec_subject_to_change.h>
+
+#ifdef SVE_OVERLOADED_FORMS
+// A simple used,unused... macro, long enough to represent any SVE builtin.§
+#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3
+#else
+#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4
+#endif
+
+// CHECK-LABEL: @test_svreinterpret_svbool_svcnt(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.taarch64.svcountt(target("aarch64.svcount") [[CNT:%.*]])
+// CHECK-NEXT: ret <vscale x 16 x i1> [[TMP0]]
+//
+// CPP-CHECK-LABEL: @_Z31test_svreinterpret_svbool_svcntu11__SVCount_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.taarch64.svcountt(target("aarch64.svcount") [[CNT:%.*]])
+// CPP-CHECK-NEXT: ret <vscale x 16 x i1> [[TMP0]]
+//
+svbool_t test_svreinterpret_svbool_svcnt(svcount_t cnt) __arm_streaming_compatible
+{
+ return SVE_ACLE_FUNC(svreinterpret,_b,,)(cnt);
+}
+
+// CHECK-LABEL: @test_svreinterpret_svcnt_svbool(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call target("aarch64.svcount") @llvm.aarch64.sve.convert.from.svbool.taarch64.svcountt(<vscale x 16 x i1> [[PG:%.*]])
+// CHECK-NEXT: ret target("aarch64.svcount") [[TMP0]]
+//
+// CPP-CHECK-LABEL: @_Z31test_svreinterpret_svcnt_svboolu10__SVBool_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call target("aarch64.svcount") @llvm.aarch64.sve.convert.from.svbool.taarch64.svcountt(<vscale x 16 x i1> [[PG:%.*]])
+// CPP-CHECK-NEXT: ret target("aarch64.svcount") [[TMP0]]
+//
+svcount_t test_svreinterpret_svcnt_svbool(svbool_t pg) __arm_streaming_compatible
+{
+ return SVE_ACLE_FUNC(svreinterpret,_c,,)(pg);
+}
clang/test/CodeGen/aarch64-sme2-intrinsics/acle_sme2_vector_qrshr.c
@@ -0,0 +1,343 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// REQUIRES: aarch64-registered-target
+
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme2 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,instcombine,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme2 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -passes=mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme2 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,instcombine,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme2 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -passes=mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sme2 -target-feature +sme-f64f64 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s
+
+#include <arm_sme_draft_spec_subject_to_change.h>
+
+#ifdef SVE_OVERLOADED_FORMS
+// A simple used,unused... macro, long enough to represent any SVE builtin.
+#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED,A5) A1##A3##A5
+#else
+#define SVE_ACLE_FUNC(A1,A2,A3,A4,A5) A1##A2##A3##A4##A5
+#endif
+
+// SVQRSHR
+
+// CHECK-LABEL: @test_svsqrshr_u16_u32_x4(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv8i32(<vscale x 8 x i32> [[ZN:%.*]], i64 0)
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv8i32(<vscale x 8 x i32> [[ZN]], i64 4)
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.uqrshr.x2.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], i32 16)
+// CHECK-NEXT: ret <vscale x 8 x i16> [[TMP2]]
+//
+// CPP-CHECK-LABEL: @_Z24test_svsqrshr_u16_u32_x412svuint32x2_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv8i32(<vscale x 8 x i32> [[ZN:%.*]], i64 0)
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv8i32(<vscale x 8 x i32> [[ZN]], i64 4)
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.uqrshr.x2.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], i32 16)
+// CPP-CHECK-NEXT: ret <vscale x 8 x i16> [[TMP2]]
+//
+svuint16_t test_svsqrshr_u16_u32_x4(svuint32x2_t zn) __arm_streaming {
+ return SVE_ACLE_FUNC(svqrshr,_n,_u16,_u32_x2,)(zn, 16);
+}
+
+// CHECK-LABEL: @test_svsqrshr_s16_s32_x4(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv8i32(<vscale x 8 x i32> [[ZN:%.*]], i64 0)
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv8i32(<vscale x 8 x i32> [[ZN]], i64 4)
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshr.x2.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], i32 16)
+// CHECK-NEXT: ret <vscale x 8 x i16> [[TMP2]]
+//
+// CPP-CHECK-LABEL: @_Z24test_svsqrshr_s16_s32_x411svint32x2_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv8i32(<vscale x 8 x i32> [[ZN:%.*]], i64 0)
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv8i32(<vscale x 8 x i32> [[ZN]], i64 4)
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshr.x2.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], i32 16)
+// CPP-CHECK-NEXT: ret <vscale x 8 x i16> [[TMP2]]
+//
+svint16_t test_svsqrshr_s16_s32_x4(svint32x2_t zn) __arm_streaming {
+ return SVE_ACLE_FUNC(svqrshr,_n,_s16,_s32_x2,)(zn, 16);
+}
+
+// CHECK-LABEL: @test_svsqrshr_u8_u32_x4(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN:%.*]], i64 0)
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 4)
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 8)
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 12)
+// CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 16 x i8> @llvm.aarch64.sve.uqrshr.x4.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> [[TMP2]], <vscale x 4 x i32> [[TMP3]], i32 8)
+// CHECK-NEXT: ret <vscale x 16 x i8> [[TMP4]]
+//
+// CPP-CHECK-LABEL: @_Z23test_svsqrshr_u8_u32_x412svuint32x4_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN:%.*]], i64 0)
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 4)
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 8)
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 12)
+// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 16 x i8> @llvm.aarch64.sve.uqrshr.x4.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> [[TMP2]], <vscale x 4 x i32> [[TMP3]], i32 8)
+// CPP-CHECK-NEXT: ret <vscale x 16 x i8> [[TMP4]]
+//
+svuint8_t test_svsqrshr_u8_u32_x4(svuint32x4_t zn) __arm_streaming {
+ return SVE_ACLE_FUNC(svqrshr,_n,_u8,_u32_x4,)(zn, 8);
+}
+
+// CHECK-LABEL: @test_svsqrshr_s8_s32_x4(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN:%.*]], i64 0)
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 4)
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 8)
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 12)
+// CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 16 x i8> @llvm.aarch64.sve.sqrshr.x4.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> [[TMP2]], <vscale x 4 x i32> [[TMP3]], i32 8)
+// CHECK-NEXT: ret <vscale x 16 x i8> [[TMP4]]
+//
+// CPP-CHECK-LABEL: @_Z23test_svsqrshr_s8_s32_x411svint32x4_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN:%.*]], i64 0)
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 4)
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 8)
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 12)
+// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 16 x i8> @llvm.aarch64.sve.sqrshr.x4.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> [[TMP2]], <vscale x 4 x i32> [[TMP3]], i32 8)
+// CPP-CHECK-NEXT: ret <vscale x 16 x i8> [[TMP4]]
+//
+svint8_t test_svsqrshr_s8_s32_x4(svint32x4_t zn) __arm_streaming {
+ return SVE_ACLE_FUNC(svqrshr,_n,_s8,_s32_x4,)(zn, 8);
+}
+
+// CHECK-LABEL: @test_svsqrshr_u16_u64_x4(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN:%.*]], i64 0)
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 2)
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 4)
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 6)
+// CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.uqrshr.x4.nxv2i64(<vscale x 2 x i64> [[TMP0]], <vscale x 2 x i64> [[TMP1]], <vscale x 2 x i64> [[TMP2]], <vscale x 2 x i64> [[TMP3]], i32 16)
+// CHECK-NEXT: ret <vscale x 8 x i16> [[TMP4]]
+//
+// CPP-CHECK-LABEL: @_Z24test_svsqrshr_u16_u64_x412svuint64x4_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN:%.*]], i64 0)
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 2)
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 4)
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 6)
+// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.uqrshr.x4.nxv2i64(<vscale x 2 x i64> [[TMP0]], <vscale x 2 x i64> [[TMP1]], <vscale x 2 x i64> [[TMP2]], <vscale x 2 x i64> [[TMP3]], i32 16)
+// CPP-CHECK-NEXT: ret <vscale x 8 x i16> [[TMP4]]
+//
+svuint16_t test_svsqrshr_u16_u64_x4(svuint64x4_t zn) __arm_streaming {
+ return SVE_ACLE_FUNC(svqrshr,_n,_u16,_u64_x4,)(zn, 16);
+}
+
+// CHECK-LABEL: @test_svsqrshr_s16_s64_x4(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN:%.*]], i64 0)
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 2)
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 4)
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 6)
+// CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshr.x4.nxv2i64(<vscale x 2 x i64> [[TMP0]], <vscale x 2 x i64> [[TMP1]], <vscale x 2 x i64> [[TMP2]], <vscale x 2 x i64> [[TMP3]], i32 16)
+// CHECK-NEXT: ret <vscale x 8 x i16> [[TMP4]]
+//
+// CPP-CHECK-LABEL: @_Z24test_svsqrshr_s16_s64_x411svint64x4_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN:%.*]], i64 0)
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 2)
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 4)
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 6)
+// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshr.x4.nxv2i64(<vscale x 2 x i64> [[TMP0]], <vscale x 2 x i64> [[TMP1]], <vscale x 2 x i64> [[TMP2]], <vscale x 2 x i64> [[TMP3]], i32 16)
+// CPP-CHECK-NEXT: ret <vscale x 8 x i16> [[TMP4]]
+//
+svint16_t test_svsqrshr_s16_s64_x4(svint64x4_t zn) __arm_streaming {
+ return SVE_ACLE_FUNC(svqrshr,_n,_s16,_s64_x4,)(zn, 16);
+}
+
+// SVQRSHRN
+
+// CHECK-LABEL: @test_svsqrshrn_u8_u32_x4(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN:%.*]], i64 0)
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 4)
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 8)
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 12)
+// CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 16 x i8> @llvm.aarch64.sve.uqrshrn.x4.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> [[TMP2]], <vscale x 4 x i32> [[TMP3]], i32 8)
+// CHECK-NEXT: ret <vscale x 16 x i8> [[TMP4]]
+//
+// CPP-CHECK-LABEL: @_Z24test_svsqrshrn_u8_u32_x412svuint32x4_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN:%.*]], i64 0)
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 4)
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 8)
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 12)
+// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 16 x i8> @llvm.aarch64.sve.uqrshrn.x4.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> [[TMP2]], <vscale x 4 x i32> [[TMP3]], i32 8)
+// CPP-CHECK-NEXT: ret <vscale x 16 x i8> [[TMP4]]
+//
+svuint8_t test_svsqrshrn_u8_u32_x4(svuint32x4_t zn) __arm_streaming {
+ return SVE_ACLE_FUNC(svqrshrn,_n,_u8,_u32_x4,)(zn, 8);
+}
+
+// CHECK-LABEL: @test_svsqrshrn_s8_s32_x4(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN:%.*]], i64 0)
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 4)
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 8)
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 12)
+// CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 16 x i8> @llvm.aarch64.sve.sqrshrn.x4.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> [[TMP2]], <vscale x 4 x i32> [[TMP3]], i32 8)
+// CHECK-NEXT: ret <vscale x 16 x i8> [[TMP4]]
+//
+// CPP-CHECK-LABEL: @_Z24test_svsqrshrn_s8_s32_x411svint32x4_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN:%.*]], i64 0)
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 4)
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 8)
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 12)
+// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 16 x i8> @llvm.aarch64.sve.sqrshrn.x4.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> [[TMP2]], <vscale x 4 x i32> [[TMP3]], i32 8)
+// CPP-CHECK-NEXT: ret <vscale x 16 x i8> [[TMP4]]
+//
+svint8_t test_svsqrshrn_s8_s32_x4(svint32x4_t zn) __arm_streaming {
+ return SVE_ACLE_FUNC(svqrshrn,_n,_s8,_s32_x4,)(zn, 8);
+}
+
+// CHECK-LABEL: @test_svsqrshrn_u16_u64_x4(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN:%.*]], i64 0)
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 2)
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 4)
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 6)
+// CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.uqrshrn.x4.nxv2i64(<vscale x 2 x i64> [[TMP0]], <vscale x 2 x i64> [[TMP1]], <vscale x 2 x i64> [[TMP2]], <vscale x 2 x i64> [[TMP3]], i32 16)
+// CHECK-NEXT: ret <vscale x 8 x i16> [[TMP4]]
+//
+// CPP-CHECK-LABEL: @_Z25test_svsqrshrn_u16_u64_x412svuint64x4_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN:%.*]], i64 0)
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 2)
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 4)
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 6)
+// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.uqrshrn.x4.nxv2i64(<vscale x 2 x i64> [[TMP0]], <vscale x 2 x i64> [[TMP1]], <vscale x 2 x i64> [[TMP2]], <vscale x 2 x i64> [[TMP3]], i32 16)
+// CPP-CHECK-NEXT: ret <vscale x 8 x i16> [[TMP4]]
+//
+svuint16_t test_svsqrshrn_u16_u64_x4(svuint64x4_t zn) __arm_streaming {
+ return SVE_ACLE_FUNC(svqrshrn,_n,_u16,_u64_x4,)(zn, 16);
+}
+
+// CHECK-LABEL: @test_svsqrshrn_s16_s64_x4(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN:%.*]], i64 0)
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 2)
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 4)
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 6)
+// CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshrn.x4.nxv2i64(<vscale x 2 x i64> [[TMP0]], <vscale x 2 x i64> [[TMP1]], <vscale x 2 x i64> [[TMP2]], <vscale x 2 x i64> [[TMP3]], i32 16)
+// CHECK-NEXT: ret <vscale x 8 x i16> [[TMP4]]
+//
+// CPP-CHECK-LABEL: @_Z25test_svsqrshrn_s16_s64_x411svint64x4_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN:%.*]], i64 0)
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 2)
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 4)
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 6)
+// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshrn.x4.nxv2i64(<vscale x 2 x i64> [[TMP0]], <vscale x 2 x i64> [[TMP1]], <vscale x 2 x i64> [[TMP2]], <vscale x 2 x i64> [[TMP3]], i32 16)
+// CPP-CHECK-NEXT: ret <vscale x 8 x i16> [[TMP4]]
+//
+svint16_t test_svsqrshrn_s16_s64_x4(svint64x4_t zn) __arm_streaming {
+ return SVE_ACLE_FUNC(svqrshrn,_n,_s16,_s64_x4,)(zn, 16);
+}
+
+// SVSQRSHRU
+
+// CHECK-LABEL: @test_svsvqrshru_u16_s32_x2(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv8i32(<vscale x 8 x i32> [[ZN:%.*]], i64 0)
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv8i32(<vscale x 8 x i32> [[ZN]], i64 4)
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshru.x2.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], i32 16)
+// CHECK-NEXT: ret <vscale x 8 x i16> [[TMP2]]
+//
+// CPP-CHECK-LABEL: @_Z26test_svsvqrshru_u16_s32_x211svint32x2_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv8i32(<vscale x 8 x i32> [[ZN:%.*]], i64 0)
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv8i32(<vscale x 8 x i32> [[ZN]], i64 4)
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshru.x2.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], i32 16)
+// CPP-CHECK-NEXT: ret <vscale x 8 x i16> [[TMP2]]
+//
+svuint16_t test_svsvqrshru_u16_s32_x2(svint32x2_t zn) __arm_streaming {
+ return SVE_ACLE_FUNC(svqrshru,_n,_u16,_s32_x2,)(zn, 16);
+}
+
+// CHECK-LABEL: @test_svsqrshru_u8_s32_x4(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN:%.*]], i64 0)
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 4)
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 8)
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 12)
+// CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 16 x i8> @llvm.aarch64.sve.sqrshru.x4.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> [[TMP2]], <vscale x 4 x i32> [[TMP3]], i32 8)
+// CHECK-NEXT: ret <vscale x 16 x i8> [[TMP4]]
+//
+// CPP-CHECK-LABEL: @_Z24test_svsqrshru_u8_s32_x411svint32x4_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN:%.*]], i64 0)
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 4)
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 8)
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 12)
+// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 16 x i8> @llvm.aarch64.sve.sqrshru.x4.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> [[TMP2]], <vscale x 4 x i32> [[TMP3]], i32 8)
+// CPP-CHECK-NEXT: ret <vscale x 16 x i8> [[TMP4]]
+//
+svuint8_t test_svsqrshru_u8_s32_x4(svint32x4_t zn) __arm_streaming {
+ return SVE_ACLE_FUNC(svqrshru,_n,_u8,_s32_x4,)(zn, 8);
+}
+
+// CHECK-LABEL: @test_svsqrshru_u16_s64_x4(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN:%.*]], i64 0)
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 2)
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 4)
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 6)
+// CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshru.x4.nxv2i64(<vscale x 2 x i64> [[TMP0]], <vscale x 2 x i64> [[TMP1]], <vscale x 2 x i64> [[TMP2]], <vscale x 2 x i64> [[TMP3]], i32 16)
+// CHECK-NEXT: ret <vscale x 8 x i16> [[TMP4]]
+//
+// CPP-CHECK-LABEL: @_Z25test_svsqrshru_u16_s64_x411svint64x4_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN:%.*]], i64 0)
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 2)
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 4)
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 6)
+// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshru.x4.nxv2i64(<vscale x 2 x i64> [[TMP0]], <vscale x 2 x i64> [[TMP1]], <vscale x 2 x i64> [[TMP2]], <vscale x 2 x i64> [[TMP3]], i32 16)
+// CPP-CHECK-NEXT: ret <vscale x 8 x i16> [[TMP4]]
+//
+svuint16_t test_svsqrshru_u16_s64_x4(svint64x4_t zn) __arm_streaming {
+ return SVE_ACLE_FUNC(svqrshru,_n,_u16,_s64_x4,)(zn, 16);
+}
+
+// SQRSHRUN x 4
+
+// CHECK-LABEL: @test_svsqrshrun_u8_s32_x4(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN:%.*]], i64 0)
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 4)
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 8)
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 12)
+// CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 16 x i8> @llvm.aarch64.sve.sqrshrun.x4.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> [[TMP2]], <vscale x 4 x i32> [[TMP3]], i32 32)
+// CHECK-NEXT: ret <vscale x 16 x i8> [[TMP4]]
+//
+// CPP-CHECK-LABEL: @_Z25test_svsqrshrun_u8_s32_x411svint32x4_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN:%.*]], i64 0)
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 4)
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 8)
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 4 x i32> @llvm.vector.extract.nxv4i32.nxv16i32(<vscale x 16 x i32> [[ZN]], i64 12)
+// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 16 x i8> @llvm.aarch64.sve.sqrshrun.x4.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], <vscale x 4 x i32> [[TMP2]], <vscale x 4 x i32> [[TMP3]], i32 32)
+// CPP-CHECK-NEXT: ret <vscale x 16 x i8> [[TMP4]]
+//
+svuint8_t test_svsqrshrun_u8_s32_x4(svint32x4_t zn) __arm_streaming {
+ return SVE_ACLE_FUNC(svqrshrun,_n,_u8,_s32_x4,)(zn, 32);
+}
+
+// CHECK-LABEL: @test_svsqrshrun_u16_s64_x4(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN:%.*]], i64 0)
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 2)
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 4)
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 6)
+// CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshrun.x4.nxv2i64(<vscale x 2 x i64> [[TMP0]], <vscale x 2 x i64> [[TMP1]], <vscale x 2 x i64> [[TMP2]], <vscale x 2 x i64> [[TMP3]], i32 64)
+// CHECK-NEXT: ret <vscale x 8 x i16> [[TMP4]]
+//
+// CPP-CHECK-LABEL: @_Z26test_svsqrshrun_u16_s64_x411svint64x4_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN:%.*]], i64 0)
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 2)
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 4)
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 2 x i64> @llvm.vector.extract.nxv2i64.nxv8i64(<vscale x 8 x i64> [[ZN]], i64 6)
+// CPP-CHECK-NEXT: [[TMP4:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshrun.x4.nxv2i64(<vscale x 2 x i64> [[TMP0]], <vscale x 2 x i64> [[TMP1]], <vscale x 2 x i64> [[TMP2]], <vscale x 2 x i64> [[TMP3]], i32 64)
+// CPP-CHECK-NEXT: ret <vscale x 8 x i16> [[TMP4]]
+//
+svuint16_t test_svsqrshrun_u16_s64_x4(svint64x4_t zn) __arm_streaming {
+ return SVE_ACLE_FUNC(svqrshrun,_n,_u16,_s64_x4,)(zn, 64);
+}
clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_create2_bool.c
@@ -0,0 +1,38 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s \
+// RUN: | opt -S -passes=mem2reg,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s \
+// RUN: | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s \
+// RUN: | opt -S -passes=mem2reg,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s\
+// RUN: | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s
+
+// REQUIRES: aarch64-registered-target
+
+#include <arm_sve.h>
+
+#ifdef SVE_OVERLOADED_FORMS
+// A simple used,unused... macro, long enough to represent any SVE builtin.
+#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3
+#else
+#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4
+#endif
+
+// CHECK-LABEL: @test_svcreate2_s8(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 32 x i1> @llvm.vector.insert.nxv32i1.nxv16i1(<vscale x 32 x i1> poison, <vscale x 16 x i1> [[X0:%.*]], i64 0)
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 32 x i1> @llvm.vector.insert.nxv32i1.nxv16i1(<vscale x 32 x i1> [[TMP0]], <vscale x 16 x i1> [[X1:%.*]], i64 16)
+// CHECK-NEXT: ret <vscale x 32 x i1> [[TMP1]]
+//
+// CPP-CHECK-LABEL: @_Z17test_svcreate2_s8u10__SVBool_tS_(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 32 x i1> @llvm.vector.insert.nxv32i1.nxv16i1(<vscale x 32 x i1> poison, <vscale x 16 x i1> [[X0:%.*]], i64 0)
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 32 x i1> @llvm.vector.insert.nxv32i1.nxv16i1(<vscale x 32 x i1> [[TMP0]], <vscale x 16 x i1> [[X1:%.*]], i64 16)
+// CPP-CHECK-NEXT: ret <vscale x 32 x i1> [[TMP1]]
+//
+svboolx2_t test_svcreate2_s8(svbool_t x0, svbool_t x1)
+{
+ return SVE_ACLE_FUNC(svcreate2,_b8,,)(x0, x1);
+}
clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_create4_bool.c
@@ -0,0 +1,42 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s \
+// RUN: | opt -S -passes=mem2reg,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s \
+// RUN: | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s \
+// RUN: | opt -S -passes=mem2reg,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s\
+// RUN: | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s
+
+// REQUIRES: aarch64-registered-target
+
+#include <arm_sve.h>
+
+#ifdef SVE_OVERLOADED_FORMS
+// A simple used,unused... macro, long enough to represent any SVE builtin.
+#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3
+#else
+#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4
+#endif
+
+// CHECK-LABEL: @test_svcreate4_b8(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> poison, <vscale x 16 x i1> [[X0:%.*]], i64 0)
+// CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> [[TMP0]], <vscale x 16 x i1> [[X1:%.*]], i64 16)
+// CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> [[TMP1]], <vscale x 16 x i1> [[X2:%.*]], i64 32)
+// CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> [[TMP2]], <vscale x 16 x i1> [[X4:%.*]], i64 48)
+// CHECK-NEXT: ret <vscale x 64 x i1> [[TMP3]]
+//
+// CPP-CHECK-LABEL: @_Z17test_svcreate4_b8u10__SVBool_tS_S_S_(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> poison, <vscale x 16 x i1> [[X0:%.*]], i64 0)
+// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> [[TMP0]], <vscale x 16 x i1> [[X1:%.*]], i64 16)
+// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> [[TMP1]], <vscale x 16 x i1> [[X2:%.*]], i64 32)
+// CPP-CHECK-NEXT: [[TMP3:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> [[TMP2]], <vscale x 16 x i1> [[X4:%.*]], i64 48)
+// CPP-CHECK-NEXT: ret <vscale x 64 x i1> [[TMP3]]
+//
+svboolx4_t test_svcreate4_b8(svbool_t x0, svbool_t x1, svbool_t x2, svbool_t x4)
+{
+ return SVE_ACLE_FUNC(svcreate4,_b8,,)(x0, x1, x2, x4);
+}
clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_get2_bool.c
@@ -0,0 +1,49 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s \
+// RUN: | opt -S -passes=mem2reg,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s \
+// RUN: | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s \
+// RUN: | opt -S -passes=mem2reg,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s\
+// RUN: | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s
+// REQUIRES: aarch64-registered-target
+#include <arm_sve.h>
+
+#ifdef SVE_OVERLOADED_FORMS
+// A simple used,unused... macro, long enough to represent any SVE builtin.
+#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3
+#else
+#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4
+#endif
+
+// CHECK-LABEL: @test_svget2_b8_0(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.vector.extract.nxv16i1.nxv32i1(<vscale x 32 x i1> [[TUPLE:%.*]], i64 0)
+// CHECK-NEXT: ret <vscale x 16 x i1> [[TMP0]]
+//
+// CPP-CHECK-LABEL: @_Z16test_svget2_b8_010svboolx2_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.vector.extract.nxv16i1.nxv32i1(<vscale x 32 x i1> [[TUPLE:%.*]], i64 0)
+// CPP-CHECK-NEXT: ret <vscale x 16 x i1> [[TMP0]]
+//
+svbool_t test_svget2_b8_0(svboolx2_t tuple)
+{
+ return SVE_ACLE_FUNC(svget2,_b8,,)(tuple, 0);
+}
+
+// CHECK-LABEL: @test_svget2_b8_1(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.vector.extract.nxv16i1.nxv32i1(<vscale x 32 x i1> [[TUPLE:%.*]], i64 16)
+// CHECK-NEXT: ret <vscale x 16 x i1> [[TMP0]]
+//
+// CPP-CHECK-LABEL: @_Z16test_svget2_b8_110svboolx2_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.vector.extract.nxv16i1.nxv32i1(<vscale x 32 x i1> [[TUPLE:%.*]], i64 16)
+// CPP-CHECK-NEXT: ret <vscale x 16 x i1> [[TMP0]]
+//
+svbool_t test_svget2_b8_1(svboolx2_t tuple)
+{
+ return SVE_ACLE_FUNC(svget2,_b8,,)(tuple, 1);
+}
clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_get4_bool.c
@@ -0,0 +1,72 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s \
+// RUN: | opt -S -passes=mem2reg,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s \
+// RUN: | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s \
+// RUN: | opt -S -passes=mem2reg,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s\
+// RUN: | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s
+
+// REQUIRES: aarch64-registered-target
+
+#include <arm_sve.h>
+
+#ifdef SVE_OVERLOADED_FORMS
+// A simple used,unused... macro, long enough to represent any SVE builtin.
+#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3
+#else
+#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4
+#endif
+
+// NOTE: For these tests clang converts the struct parameter into
+// several parameters, one for each member of the original struct.
+// CHECK-LABEL: @test_svget4_b8_0(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.vector.extract.nxv16i1.nxv64i1(<vscale x 64 x i1> [[TUPLE:%.*]], i64 0)
+// CHECK-NEXT: ret <vscale x 16 x i1> [[TMP0]]
+//
+// CPP-CHECK-LABEL: @_Z16test_svget4_b8_010svboolx4_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.vector.extract.nxv16i1.nxv64i1(<vscale x 64 x i1> [[TUPLE:%.*]], i64 0)
+// CPP-CHECK-NEXT: ret <vscale x 16 x i1> [[TMP0]]
+//
+svbool_t test_svget4_b8_0(svboolx4_t tuple)
+{
+ return SVE_ACLE_FUNC(svget4,_b8,,)(tuple, 0);
+}
+
+// NOTE: For these tests clang converts the struct parameter into
+// several parameters, one for each member of the original struct.
+// CHECK-LABEL: @test_svget4_b8_1(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.vector.extract.nxv16i1.nxv64i1(<vscale x 64 x i1> [[TUPLE:%.*]], i64 16)
+// CHECK-NEXT: ret <vscale x 16 x i1> [[TMP0]]
+//
+// CPP-CHECK-LABEL: @_Z16test_svget4_b8_110svboolx4_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.vector.extract.nxv16i1.nxv64i1(<vscale x 64 x i1> [[TUPLE:%.*]], i64 16)
+// CPP-CHECK-NEXT: ret <vscale x 16 x i1> [[TMP0]]
+//
+svbool_t test_svget4_b8_1(svboolx4_t tuple)
+{
+ return SVE_ACLE_FUNC(svget4,_b8,,)(tuple, 1);
+}
+
+// NOTE: For these tests clang converts the struct parameter into
+// several parameters, one for each member of the original struct.
+// CHECK-LABEL: @test_svget4_b8_3(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.vector.extract.nxv16i1.nxv64i1(<vscale x 64 x i1> [[TUPLE:%.*]], i64 48)
+// CHECK-NEXT: ret <vscale x 16 x i1> [[TMP0]]
+//
+// CPP-CHECK-LABEL: @_Z16test_svget4_b8_310svboolx4_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.vector.extract.nxv16i1.nxv64i1(<vscale x 64 x i1> [[TUPLE:%.*]], i64 48)
+// CPP-CHECK-NEXT: ret <vscale x 16 x i1> [[TMP0]]
+//
+svbool_t test_svget4_b8_3(svboolx4_t tuple)
+{
+ return SVE_ACLE_FUNC(svget4,_b8,,)(tuple, 3);
+}
clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_set2_bool.c
@@ -0,0 +1,52 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s \
+// RUN: | opt -S -passes=mem2reg,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s \
+// RUN: | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s \
+// RUN: | opt -S -passes=mem2reg,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s\
+// RUN: | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s
+
+// REQUIRES: aarch64-registered-target
+
+#include <arm_sve.h>
+
+#ifdef SVE_OVERLOADED_FORMS
+// A simple used,unused... macro, long enough to represent any SVE builtin.
+#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3
+#else
+#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4
+#endif
+
+// CHECK-LABEL: @test_svset2_b8_0(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 32 x i1> @llvm.vector.insert.nxv32i1.nxv16i1(<vscale x 32 x i1> [[TUPLE:%.*]], <vscale x 16 x i1> [[X:%.*]], i64 0)
+// CHECK-NEXT: ret <vscale x 32 x i1> [[TMP0]]
+//
+// CPP-CHECK-LABEL: @_Z16test_svset2_b8_010svboolx2_tu10__SVBool_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 32 x i1> @llvm.vector.insert.nxv32i1.nxv16i1(<vscale x 32 x i1> [[TUPLE:%.*]], <vscale x 16 x i1> [[X:%.*]], i64 0)
+// CPP-CHECK-NEXT: ret <vscale x 32 x i1> [[TMP0]]
+//
+svboolx2_t test_svset2_b8_0(svboolx2_t tuple, svbool_t x)
+{
+ return SVE_ACLE_FUNC(svset2,_b8,,)(tuple, 0, x);
+}
+
+// CHECK-LABEL: @test_svset2_b8_1(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 32 x i1> @llvm.vector.insert.nxv32i1.nxv16i1(<vscale x 32 x i1> [[TUPLE:%.*]], <vscale x 16 x i1> [[X:%.*]], i64 16)
+// CHECK-NEXT: ret <vscale x 32 x i1> [[TMP0]]
+//
+// CPP-CHECK-LABEL: @_Z16test_svset2_b8_110svboolx2_tu10__SVBool_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 32 x i1> @llvm.vector.insert.nxv32i1.nxv16i1(<vscale x 32 x i1> [[TUPLE:%.*]], <vscale x 16 x i1> [[X:%.*]], i64 16)
+// CPP-CHECK-NEXT: ret <vscale x 32 x i1> [[TMP0]]
+//
+svboolx2_t test_svset2_b8_1(svboolx2_t tuple, svbool_t x)
+{
+ return SVE_ACLE_FUNC(svset2,_b8,,)(tuple, 1, x);
+}
+
clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_set4_bool.c
@@ -0,0 +1,66 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s \
+// RUN: | opt -S -passes=mem2reg,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s \
+// RUN: | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s \
+// RUN: | opt -S -passes=mem2reg,tailcallelim | FileCheck %s
+// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s\
+// RUN: | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s
+// REQUIRES: aarch64-registered-target
+
+#include <arm_sve.h>
+
+#ifdef SVE_OVERLOADED_FORMS
+// A simple used,unused... macro, long enough to represent any SVE builtin.
+#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED) A1##A3
+#else
+#define SVE_ACLE_FUNC(A1,A2,A3,A4) A1##A2##A3##A4
+#endif
+
+
+// CHECK-LABEL: @test_svset4_b8_0(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> [[TUPLE:%.*]], <vscale x 16 x i1> [[X:%.*]], i64 0)
+// CHECK-NEXT: ret <vscale x 64 x i1> [[TMP0]]
+//
+// CPP-CHECK-LABEL: @_Z16test_svset4_b8_010svboolx4_tu10__SVBool_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> [[TUPLE:%.*]], <vscale x 16 x i1> [[X:%.*]], i64 0)
+// CPP-CHECK-NEXT: ret <vscale x 64 x i1> [[TMP0]]
+//
+svboolx4_t test_svset4_b8_0(svboolx4_t tuple, svbool_t x)
+{
+ return SVE_ACLE_FUNC(svset4,_b8,,)(tuple, 0, x);
+}
+
+// CHECK-LABEL: @test_svset4_b8_1(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> [[TUPLE:%.*]], <vscale x 16 x i1> [[X:%.*]], i64 16)
+// CHECK-NEXT: ret <vscale x 64 x i1> [[TMP0]]
+//
+// CPP-CHECK-LABEL: @_Z16test_svset4_b8_110svboolx4_tu10__SVBool_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> [[TUPLE:%.*]], <vscale x 16 x i1> [[X:%.*]], i64 16)
+// CPP-CHECK-NEXT: ret <vscale x 64 x i1> [[TMP0]]
+//
+svboolx4_t test_svset4_b8_1(svboolx4_t tuple, svbool_t x)
+{
+ return SVE_ACLE_FUNC(svset4,_b8,,)(tuple, 1, x);
+}
+
+// CHECK-LABEL: @test_svset4_b8_3(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> [[TUPLE:%.*]], <vscale x 16 x i1> [[X:%.*]], i64 48)
+// CHECK-NEXT: ret <vscale x 64 x i1> [[TMP0]]
+//
+// CPP-CHECK-LABEL: @_Z16test_svset4_b8_310svboolx4_tu10__SVBool_t(
+// CPP-CHECK-NEXT: entry:
+// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 64 x i1> @llvm.vector.insert.nxv64i1.nxv16i1(<vscale x 64 x i1> [[TUPLE:%.*]], <vscale x 16 x i1> [[X:%.*]], i64 48)
+// CPP-CHECK-NEXT: ret <vscale x 64 x i1> [[TMP0]]
+//
+svboolx4_t test_svset4_b8_3(svboolx4_t tuple, svbool_t x)
+{
+ return SVE_ACLE_FUNC(svset4,_b8,,)(tuple, 3, x);
+}
clang/test/CodeGen/arm-target-features.c
@@ -113,6 +113,9 @@
// RUN: %clang_cc1 -triple thumb-linux-gnueabi -target-cpu cortex-m85 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-ARMV81M-CORTEX-M85-LINUX // RUN: %clang_cc1 -triple thumb-linux-gnueabi -target-cpu cortex-m85 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-ARMV81M-CORTEX-M85-LINUX
// CHECK-ARMV81M-CORTEX-M85-LINUX: "target-features"="+armv8.1-m.main,+dsp,+fp-armv8d16,+fp-armv8d16sp,+fp16,+fp64,+fullfp16,+hwdiv,+lob,+mve,+mve.fp,+pacbti,+ras,+thumb-mode,+vfp2,+vfp2sp,+vfp3d16,+vfp3d16sp,+vfp4d16,+vfp4d16sp" // CHECK-ARMV81M-CORTEX-M85-LINUX: "target-features"="+armv8.1-m.main,+dsp,+fp-armv8d16,+fp-armv8d16sp,+fp16,+fp64,+fullfp16,+hwdiv,+lob,+mve,+mve.fp,+pacbti,+ras,+thumb-mode,+vfp2,+vfp2sp,+vfp3d16,+vfp3d16sp,+vfp4d16,+vfp4d16sp"
+// RUN: %clang_cc1 -triple thumb-linux-gnueabi -target-cpu cortex-m52 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-ARMV81M-CORTEX-M52-LINUX
+// CHECK-ARMV81M-CORTEX-M52-LINUX: "target-features"="+armv8.1-m.main,+dsp,+fp-armv8d16,+fp-armv8d16sp,+fp16,+fp64,+fullfp16,+hwdiv,+lob,+mve,+mve.fp,+pacbti,+ras,+thumb-mode,+vfp2,+vfp2sp,+vfp3d16,+vfp3d16sp,+vfp4d16,+vfp4d16sp"
+
// RUN: %clang_cc1 -triple thumbv9.3a-linux-gnueabihf -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-ARCH93 // RUN: %clang_cc1 -triple thumbv9.3a-linux-gnueabihf -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-ARCH93
// CHECK-ARCH93: "target-features"="+armv9.3-a,+thumb-mode,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8.7a,+v8.8a,+v9.1a,+v9.2a,+v9.3a,+v9a" // CHECK-ARCH93: "target-features"="+armv9.3-a,+thumb-mode,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8.6a,+v8.7a,+v8.8a,+v9.1a,+v9.2a,+v9.3a,+v9a"
clang/test/CodeGen/scoped-atomic-ops.c
@@ -0,0 +1,331 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple=amdgcn-amd-amdhsa -ffreestanding \
+// RUN: -fvisibility=hidden | FileCheck %s
+
+// CHECK-LABEL: define hidden i32 @fi1a(
+// CHECK: [[TMP0:%.*]] = load atomic i32, ptr [[PTR0:.+]] syncscope("one-as") monotonic, align 4
+// CHECK: [[TMP1:%.*]] = load atomic i32, ptr [[PTR1:.+]] syncscope("agent-one-as") monotonic, align 4
+// CHECK: [[TMP2:%.*]] = load atomic i32, ptr [[PTR2:.+]] syncscope("workgroup-one-as") monotonic, align 4
+// CHECK: [[TMP3:%.*]] = load atomic i32, ptr [[PTR3:.+]] syncscope("wavefront-one-as") monotonic, align 4
+// CHECK: [[TMP4:%.*]] = load atomic i32, ptr [[PTR4:.+]] syncscope("singlethread-one-as") monotonic, align 4
+int fi1a(int *i) {
+ int v;
+ __scoped_atomic_load(i, &v, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+ __scoped_atomic_load(i, &v, __ATOMIC_RELAXED, __MEMORY_SCOPE_DEVICE);
+ __scoped_atomic_load(i, &v, __ATOMIC_RELAXED, __MEMORY_SCOPE_WRKGRP);
+ __scoped_atomic_load(i, &v, __ATOMIC_RELAXED, __MEMORY_SCOPE_WVFRNT);
+ __scoped_atomic_load(i, &v, __ATOMIC_RELAXED, __MEMORY_SCOPE_SINGLE);
+ return v;
+}
+
+// CHECK-LABEL: define hidden i32 @fi1b(
+// CHECK: [[TMP0:%.*]] = load atomic i32, ptr [[PTR0:%.+]] syncscope("one-as") monotonic, align 4
+// CHECK: [[TMP1:%.*]] = load atomic i32, ptr [[PTR1:%.+]] syncscope("agent-one-as") monotonic, align 4
+// CHECK: [[TMP2:%.*]] = load atomic i32, ptr [[PTR2:%.+]] syncscope("workgroup-one-as") monotonic, align 4
+// CHECK: [[TMP3:%.*]] = load atomic i32, ptr [[PTR3:%.+]] syncscope("wavefront-one-as") monotonic, align 4
+// CHECK: [[TMP4:%.*]] = load atomic i32, ptr [[PTR4:%.+]] syncscope("singlethread-one-as") monotonic, align 4
+//
+int fi1b(int *i) {
+ *i = __scoped_atomic_load_n(i, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+ *i = __scoped_atomic_load_n(i, __ATOMIC_RELAXED, __MEMORY_SCOPE_DEVICE);
+ *i = __scoped_atomic_load_n(i, __ATOMIC_RELAXED, __MEMORY_SCOPE_WRKGRP);
+ *i = __scoped_atomic_load_n(i, __ATOMIC_RELAXED, __MEMORY_SCOPE_WVFRNT);
+ *i = __scoped_atomic_load_n(i, __ATOMIC_RELAXED, __MEMORY_SCOPE_SINGLE);
+ return *i;
+}
+
+// CHECK-LABEL: define hidden void @fi2a(
+// CHECK: store atomic i32 [[TMP0:%.+]], ptr [[PTR0:%.+]] syncscope("one-as") monotonic, align 4
+// CHECK: store atomic i32 [[TMP1:%.+]], ptr [[PTR1:%.+]] syncscope("agent-one-as") monotonic, align 4
+// CHECK: store atomic i32 [[TMP2:%.+]], ptr [[PTR2:%.+]] syncscope("workgroup-one-as") monotonic, align 4
+// CHECK: store atomic i32 [[TMP3:%.+]], ptr [[PTR3:%.+]] syncscope("wavefront-one-as") monotonic, align 4
+// CHECK: store atomic i32 [[TMP4:%.+]], ptr [[PTR4:%.+]] syncscope("singlethread-one-as") monotonic, align 4
+//
+void fi2a(int *i) {
+ int v = 1;
+ __scoped_atomic_store(i, &v, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+ __scoped_atomic_store(i, &v, __ATOMIC_RELAXED, __MEMORY_SCOPE_DEVICE);
+ __scoped_atomic_store(i, &v, __ATOMIC_RELAXED, __MEMORY_SCOPE_WRKGRP);
+ __scoped_atomic_store(i, &v, __ATOMIC_RELAXED, __MEMORY_SCOPE_WVFRNT);
+ __scoped_atomic_store(i, &v, __ATOMIC_RELAXED, __MEMORY_SCOPE_SINGLE);
+}
+
+// CHECK-LABEL: define hidden void @fi2b(
+// CHECK: store atomic i32 [[TMP0:%.+]], ptr [[PTR0:%.+]] syncscope("one-as") monotonic, align 4
+// CHECK: store atomic i32 [[TMP1:%.+]], ptr [[PTR1:%.+]] syncscope("agent-one-as") monotonic, align 4
+// CHECK: store atomic i32 [[TMP2:%.+]], ptr [[PTR2:%.+]] syncscope("workgroup-one-as") monotonic, align 4
+// CHECK: store atomic i32 [[TMP3:%.+]], ptr [[PTR3:%.+]] syncscope("wavefront-one-as") monotonic, align 4
+// CHECK: store atomic i32 [[TMP4:%.+]], ptr [[PTR4:%.+]] syncscope("singlethread-one-as") monotonic, align 4
+void fi2b(int *i) {
+ __scoped_atomic_store_n(i, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+ __scoped_atomic_store_n(i, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_DEVICE);
+ __scoped_atomic_store_n(i, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_WRKGRP);
+ __scoped_atomic_store_n(i, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_WVFRNT);
+ __scoped_atomic_store_n(i, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SINGLE);
+}
+
+// CHECK-LABEL: define hidden void @fi3a(
+// CHECK: [[TMP0:%.*]] = atomicrmw add ptr [[PTR0:%.+]], i32 [[VAL0:.+]] syncscope("one-as") monotonic, align 4
+// CHECK: [[TMP1:%.*]] = atomicrmw sub ptr [[PTR1:%.+]], i32 [[VAL1:.+]] syncscope("one-as") monotonic, align 4
+// CHECK: [[TMP2:%.*]] = atomicrmw and ptr [[PTR2:%.+]], i32 [[VAL2:.+]] syncscope("one-as") monotonic, align 4
+// CHECK: [[TMP3:%.*]] = atomicrmw or ptr [[PTR3:%.+]], i32 [[VAL3:.+]] syncscope("one-as") monotonic, align 4
+// CHECK: [[TMP4:%.*]] = atomicrmw xor ptr [[PTR4:%.+]], i32 [[VAL4:.+]] syncscope("one-as") monotonic, align 4
+// CHECK: [[TMP5:%.*]] = atomicrmw nand ptr [[PTR5:%.+]], i32 [[VAL5:.+]] syncscope("one-as") monotonic, align 4
+// CHECK: [[TMP6:%.*]] = atomicrmw min ptr [[PTR6:%.+]], i32 [[VAL6:.+]] syncscope("one-as") monotonic, align 4
+// CHECK: [[TMP7:%.*]] = atomicrmw max ptr [[PTR7:%.+]], i32 [[VAL7:.+]] syncscope("one-as") monotonic, align 4
+void fi3a(int *a, int *b, int *c, int *d, int *e, int *f, int *g, int *h) {
+ *a = __scoped_atomic_fetch_add(a, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+ *b = __scoped_atomic_fetch_sub(b, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+ *c = __scoped_atomic_fetch_and(c, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+ *d = __scoped_atomic_fetch_or(d, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+ *e = __scoped_atomic_fetch_xor(e, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+ *f = __scoped_atomic_fetch_nand(f, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+ *g = __scoped_atomic_fetch_min(g, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+ *h = __scoped_atomic_fetch_max(h, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+}
+
+// CHECK-LABEL: define hidden void @fi3b(
+// CHECK: [[TMP0:%.*]] = atomicrmw add ptr [[PTR0:%.+]], i32 [[VAL0:.+]] syncscope("agent-one-as") monotonic, align 4
+// CHECK: [[TMP1:%.*]] = atomicrmw sub ptr [[PTR1:%.+]], i32 [[VAL1:.+]] syncscope("agent-one-as") monotonic, align 4
+// CHECK: [[TMP2:%.*]] = atomicrmw and ptr [[PTR2:%.+]], i32 [[VAL2:.+]] syncscope("agent-one-as") monotonic, align 4
+// CHECK: [[TMP3:%.*]] = atomicrmw or ptr [[PTR3:%.+]], i32 [[VAL3:.+]] syncscope("agent-one-as") monotonic, align 4
+// CHECK: [[TMP4:%.*]] = atomicrmw xor ptr [[PTR4:%.+]], i32 [[VAL4:.+]] syncscope("agent-one-as") monotonic, align 4
+// CHECK: [[TMP5:%.*]] = atomicrmw nand ptr [[PTR5:%.+]], i32 [[VAL5:.+]] syncscope("agent-one-as") monotonic, align 4
+// CHECK: [[TMP6:%.*]] = atomicrmw min ptr [[PTR6:%.+]], i32 [[VAL6:.+]] syncscope("agent-one-as") monotonic, align 4
+// CHECK: [[TMP7:%.*]] = atomicrmw max ptr [[PTR7:%.+]], i32 [[VAL7:.+]] syncscope("agent-one-as") monotonic, align 4
+void fi3b(int *a, int *b, int *c, int *d, int *e, int *f, int *g, int *h) {
+ *a = __scoped_atomic_fetch_add(a, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_DEVICE);
+ *b = __scoped_atomic_fetch_sub(b, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_DEVICE);
+ *c = __scoped_atomic_fetch_and(c, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_DEVICE);
+ *d = __scoped_atomic_fetch_or(d, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_DEVICE);
+ *e = __scoped_atomic_fetch_xor(e, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_DEVICE);
+ *f = __scoped_atomic_fetch_nand(f, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_DEVICE);
+ *g = __scoped_atomic_fetch_min(g, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_DEVICE);
+ *h = __scoped_atomic_fetch_max(h, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_DEVICE);
+}
+
+// CHECK-LABEL: define hidden void @fi3c(
+// CHECK: [[TMP0:%.*]] = atomicrmw add ptr [[PTR0:%.+]], i32 [[VAL0:.+]] syncscope("workgroup-one-as") monotonic, align 4
+// CHECK: [[TMP1:%.*]] = atomicrmw sub ptr [[PTR1:%.+]], i32 [[VAL1:.+]] syncscope("workgroup-one-as") monotonic, align 4
+// CHECK: [[TMP2:%.*]] = atomicrmw and ptr [[PTR2:%.+]], i32 [[VAL2:.+]] syncscope("workgroup-one-as") monotonic, align 4
+// CHECK: [[TMP3:%.*]] = atomicrmw or ptr [[PTR3:%.+]], i32 [[VAL3:.+]] syncscope("workgroup-one-as") monotonic, align 4
+// CHECK: [[TMP4:%.*]] = atomicrmw xor ptr [[PTR4:%.+]], i32 [[VAL4:.+]] syncscope("workgroup-one-as") monotonic, align 4
+// CHECK: [[TMP5:%.*]] = atomicrmw nand ptr [[PTR5:%.+]], i32 [[VAL5:.+]] syncscope("workgroup-one-as") monotonic, align 4
+// CHECK: [[TMP6:%.*]] = atomicrmw min ptr [[PTR6:%.+]], i32 [[VAL6:.+]] syncscope("workgroup-one-as") monotonic, align 4
+// CHECK: [[TMP7:%.*]] = atomicrmw max ptr [[PTR7:%.+]], i32 [[VAL7:.+]] syncscope("workgroup-one-as") monotonic, align 4
+void fi3c(int *a, int *b, int *c, int *d, int *e, int *f, int *g, int *h) {
+ *a = __scoped_atomic_fetch_add(a, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_WRKGRP);
+ *b = __scoped_atomic_fetch_sub(b, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_WRKGRP);
+ *c = __scoped_atomic_fetch_and(c, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_WRKGRP);
+ *d = __scoped_atomic_fetch_or(d, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_WRKGRP);
+ *e = __scoped_atomic_fetch_xor(e, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_WRKGRP);
+ *f = __scoped_atomic_fetch_nand(f, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_WRKGRP);
+ *g = __scoped_atomic_fetch_min(g, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_WRKGRP);
+ *h = __scoped_atomic_fetch_max(h, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_WRKGRP);
+}
+
+// CHECK-LABEL: define hidden void @fi3d(
+// CHECK: [[TMP0:%.*]] = atomicrmw add ptr [[PTR0:%.+]], i32 [[VAL0:.+]] syncscope("wavefront-one-as") monotonic, align 4
+// CHECK: [[TMP1:%.*]] = atomicrmw sub ptr [[PTR1:%.+]], i32 [[VAL1:.+]] syncscope("wavefront-one-as") monotonic, align 4
+// CHECK: [[TMP2:%.*]] = atomicrmw and ptr [[PTR2:%.+]], i32 [[VAL2:.+]] syncscope("wavefront-one-as") monotonic, align 4
+// CHECK: [[TMP3:%.*]] = atomicrmw or ptr [[PTR3:%.+]], i32 [[VAL3:.+]] syncscope("wavefront-one-as") monotonic, align 4
+// CHECK: [[TMP4:%.*]] = atomicrmw xor ptr [[PTR4:%.+]], i32 [[VAL4:.+]] syncscope("wavefront-one-as") monotonic, align 4
+// CHECK: [[TMP5:%.*]] = atomicrmw nand ptr [[PTR5:%.+]], i32 [[VAL5:.+]] syncscope("wavefront-one-as") monotonic, align 4
+// CHECK: [[TMP6:%.*]] = atomicrmw min ptr [[PTR6:%.+]], i32 [[VAL6:.+]] syncscope("wavefront-one-as") monotonic, align 4
+// CHECK: [[TMP7:%.*]] = atomicrmw max ptr [[PTR7:%.+]], i32 [[VAL7:.+]] syncscope("wavefront-one-as") monotonic, align 4
+void fi3d(int *a, int *b, int *c, int *d, int *e, int *f, int *g, int *h) {
+ *a = __scoped_atomic_fetch_add(a, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_WVFRNT);
+ *b = __scoped_atomic_fetch_sub(b, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_WVFRNT);
+ *c = __scoped_atomic_fetch_and(c, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_WVFRNT);
+ *d = __scoped_atomic_fetch_or(d, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_WVFRNT);
+ *e = __scoped_atomic_fetch_xor(e, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_WVFRNT);
+ *f = __scoped_atomic_fetch_nand(f, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_WVFRNT);
+ *g = __scoped_atomic_fetch_min(g, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_WVFRNT);
+ *h = __scoped_atomic_fetch_max(h, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_WVFRNT);
+}
+
+// CHECK-LABEL: define hidden void @fi3e(
+// CHECK: [[TMP0:%.*]] = atomicrmw add ptr [[PTR0:%.+]], i32 [[VAL0:.+]] syncscope("singlethread-one-as") monotonic, align 4
+// CHECK: [[TMP1:%.*]] = atomicrmw sub ptr [[PTR1:%.+]], i32 [[VAL1:.+]] syncscope("singlethread-one-as") monotonic, align 4
+// CHECK: [[TMP2:%.*]] = atomicrmw and ptr [[PTR2:%.+]], i32 [[VAL2:.+]] syncscope("singlethread-one-as") monotonic, align 4
+// CHECK: [[TMP3:%.*]] = atomicrmw or ptr [[PTR3:%.+]], i32 [[VAL3:.+]] syncscope("singlethread-one-as") monotonic, align 4
+// CHECK: [[TMP4:%.*]] = atomicrmw xor ptr [[PTR4:%.+]], i32 [[VAL4:.+]] syncscope("singlethread-one-as") monotonic, align 4
+// CHECK: [[TMP5:%.*]] = atomicrmw nand ptr [[PTR5:%.+]], i32 [[VAL5:.+]] syncscope("singlethread-one-as") monotonic, align 4
+// CHECK: [[TMP6:%.*]] = atomicrmw min ptr [[PTR6:%.+]], i32 [[VAL6:.+]] syncscope("singlethread-one-as") monotonic, align 4
+// CHECK: [[TMP7:%.*]] = atomicrmw max ptr [[PTR7:%.+]], i32 [[VAL7:.+]] syncscope("singlethread-one-as") monotonic, align 4
+void fi3e(int *a, int *b, int *c, int *d, int *e, int *f, int *g, int *h) {
+ *a = __scoped_atomic_fetch_add(a, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SINGLE);
+ *b = __scoped_atomic_fetch_sub(b, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SINGLE);
+ *c = __scoped_atomic_fetch_and(c, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SINGLE);
+ *d = __scoped_atomic_fetch_or(d, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SINGLE);
+ *e = __scoped_atomic_fetch_xor(e, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SINGLE);
+ *f = __scoped_atomic_fetch_nand(f, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SINGLE);
+ *g = __scoped_atomic_fetch_min(g, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SINGLE);
+ *h = __scoped_atomic_fetch_max(h, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SINGLE);
+}
+
+// CHECK-LABEL: define hidden zeroext i1 @fi4a(
+// CHECK: [[TMP0:%.*]] = cmpxchg ptr [[PTR0:%.+]], i32 [[VAL0:.+]], i32 [[VAL1:.+]] syncscope("one-as") acquire acquire, align 4
+_Bool fi4a(int *i) {
+ int cmp = 0;
+ int desired = 1;
+ return __scoped_atomic_compare_exchange(i, &cmp, &desired, 0,
+ __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE,
+ __MEMORY_SCOPE_SYSTEM);
+}
+
+// CHECK-LABEL: define hidden zeroext i1 @fi4b(
+// CHECK: [[TMP0:%.*]] = cmpxchg ptr [[PTR0:%.+]], i32 [[VAL0:.+]], i32 [[VAL1:.+]] syncscope("agent-one-as") acquire acquire, align 4
+_Bool fi4b(int *i) {
+ int cmp = 0;
+ int desired = 1;
+ return __scoped_atomic_compare_exchange(i, &cmp, &desired, 0,
+ __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE,
+ __MEMORY_SCOPE_DEVICE);
+}
+
+// CHECK-LABEL: define hidden zeroext i1 @fi4c(
+// CHECK: [[TMP0:%.*]] = cmpxchg ptr [[PTR0:%.+]], i32 [[VAL0:.+]], i32 [[VAL1:.+]] syncscope("workgroup-one-as") acquire acquire, align 4
+_Bool fi4c(int *i) {
+ int cmp = 0;
+ int desired = 1;
+ return __scoped_atomic_compare_exchange(i, &cmp, &desired, 0,
+ __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE,
+ __MEMORY_SCOPE_WRKGRP);
+}
+
+// CHECK-LABEL: define hidden zeroext i1 @fi4d(
+// CHECK: [[TMP0:%.*]] = cmpxchg ptr [[PTR0:%.+]], i32 [[VAL0:.+]], i32 [[VAL1:.+]] syncscope("wavefront-one-as") acquire acquire, align 4
+_Bool fi4d(int *i) {
+ int cmp = 0;
+ int desired = 1;
+ return __scoped_atomic_compare_exchange(i, &cmp, &desired, 0,
+ __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE,
+ __MEMORY_SCOPE_WVFRNT);
+}
+
+// CHECK-LABEL: define hidden zeroext i1 @fi4e(
+// CHECK: [[TMP0:%.*]] = cmpxchg ptr [[PTR0:%.+]], i32 [[VAL0:.+]], i32 [[VAL1:.+]] syncscope("singlethread-one-as") acquire acquire, align 4
+_Bool fi4e(int *i) {
+ int cmp = 0;
+ int desired = 1;
+ return __scoped_atomic_compare_exchange(i, &cmp, &desired, 0,
+ __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE,
+ __MEMORY_SCOPE_SINGLE);
+}
+
+// CHECK-LABEL: define hidden zeroext i1 @fi5a(
+// CHECK: [[TMP0:%.*]] = cmpxchg weak ptr [[PTR0:%.+]], i32 [[VAL0:.+]], i32 [[VAL1:.+]] syncscope("one-as") acquire acquire, align 4
+_Bool fi5a(int *i) {
+ int cmp = 0;
+ return __scoped_atomic_compare_exchange_n(i, &cmp, 1, 1, __ATOMIC_ACQUIRE,
+ __ATOMIC_ACQUIRE,
+ __MEMORY_SCOPE_SYSTEM);
+}
+
+// CHECK-LABEL: define hidden zeroext i1 @fi5b(
+// CHECK: [[TMP0:%.*]] = cmpxchg weak ptr [[PTR0:%.+]], i32 [[VAL0:.+]], i32 [[VAL1:.+]] syncscope("agent-one-as") acquire acquire, align 4
+_Bool fi5b(int *i) {
+ int cmp = 0;
+ return __scoped_atomic_compare_exchange_n(i, &cmp, 1, 1, __ATOMIC_ACQUIRE,
+ __ATOMIC_ACQUIRE,
+ __MEMORY_SCOPE_DEVICE);
+}
+
+// CHECK-LABEL: define hidden zeroext i1 @fi5c(
+// CHECK: [[TMP0:%.*]] = cmpxchg weak ptr [[PTR0:%.+]], i32 [[VAL0:.+]], i32 [[VAL1:.+]] syncscope("workgroup-one-as") acquire acquire, align 4
+_Bool fi5c(int *i) {
+ int cmp = 0;
+ return __scoped_atomic_compare_exchange_n(
+ i, &cmp, 1, 1, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE, __MEMORY_SCOPE_WRKGRP);
+}
+
+// CHECK-LABEL: define hidden zeroext i1 @fi5d(
+// CHECK: [[TMP0:%.*]] = cmpxchg weak ptr [[PTR0:%.+]], i32 [[VAL0:.+]], i32 [[VAL1:.+]] syncscope("wavefront-one-as") acquire acquire, align 4
+_Bool fi5d(int *i) {
+ int cmp = 0;
+ return __scoped_atomic_compare_exchange_n(
+ i, &cmp, 1, 1, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE, __MEMORY_SCOPE_WVFRNT);
+}
+
+// CHECK-LABEL: define hidden zeroext i1 @fi5e(
+// CHECK: [[TMP0:%.*]] = cmpxchg weak ptr [[PTR0:%.+]], i32 [[VAL0:.+]], i32 [[VAL1:.+]] syncscope("singlethread-one-as") acquire acquire, align 4
+_Bool fi5e(int *i) {
+ int cmp = 0;
+ return __scoped_atomic_compare_exchange_n(
+ i, &cmp, 1, 1, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE, __MEMORY_SCOPE_SINGLE);
+}
+
+// CHECK-LABEL: define hidden i32 @fi6a(
+// CHECK: [[TMP0:%.*]] = atomicrmw xchg ptr [[PTR0:%.+]], i32 [[VAL0:.+]] syncscope("one-as") monotonic, align 4
+int fi6a(int *c, int *d) {
+ int ret;
+ __scoped_atomic_exchange(c, d, &ret, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+ return ret;
+}
+
+// CHECK-LABEL: define hidden i32 @fi6b(
+// CHECK: [[TMP0:%.*]] = atomicrmw xchg ptr [[PTR0:%.+]], i32 [[VAL0:.+]] syncscope("agent-one-as") monotonic, align 4
+int fi6b(int *c, int *d) {
+ int ret;
+ __scoped_atomic_exchange(c, d, &ret, __ATOMIC_RELAXED, __MEMORY_SCOPE_DEVICE);
+ return ret;
+}
+
+// CHECK-LABEL: define hidden i32 @fi6c(
+// CHECK: [[TMP0:%.*]] = atomicrmw xchg ptr [[PTR0:%.+]], i32 [[VAL0:.+]] syncscope("workgroup-one-as") monotonic, align 4
+int fi6c(int *c, int *d) {
+ int ret;
+ __scoped_atomic_exchange(c, d, &ret, __ATOMIC_RELAXED, __MEMORY_SCOPE_WRKGRP);
+ return ret;
+}
+
+// CHECK-LABEL: define hidden i32 @fi6d(
+// CHECK: [[TMP0:%.*]] = atomicrmw xchg ptr [[PTR0:%.+]], i32 [[VAL0:.+]] syncscope("wavefront-one-as") monotonic, align 4
+int fi6d(int *c, int *d) {
+ int ret;
+ __scoped_atomic_exchange(c, d, &ret, __ATOMIC_RELAXED, __MEMORY_SCOPE_WVFRNT);
+ return ret;
+}
+
+// CHECK-LABEL: define hidden i32 @fi6e(
+// CHECK: [[TMP0:%.*]] = atomicrmw xchg ptr [[PTR0:%.+]], i32 [[VAL0:.+]] syncscope("singlethread-one-as") monotonic, align 4
+int fi6e(int *c, int *d) {
+ int ret;
+ __scoped_atomic_exchange(c, d, &ret, __ATOMIC_RELAXED, __MEMORY_SCOPE_SINGLE);
+ return ret;
+}
+
+// CHECK-LABEL: define hidden zeroext i1 @fi7a(
+// CHECK: [[TMP0:%.*]] = atomicrmw xchg ptr [[PTR0:%.+]], i8 [[VAL0:.+]] syncscope("one-as") monotonic, align 1
+_Bool fi7a(_Bool *c) {
+ return __scoped_atomic_exchange_n(c, 1, __ATOMIC_RELAXED,
+ __MEMORY_SCOPE_SYSTEM);
+}
+
+// CHECK-LABEL: define hidden zeroext i1 @fi7b(
+// CHECK: [[TMP0:%.*]] = atomicrmw xchg ptr [[PTR0:%.+]], i8 [[VAL0:.+]] syncscope("agent-one-as") monotonic, align 1
+_Bool fi7b(_Bool *c) {
+ return __scoped_atomic_exchange_n(c, 1, __ATOMIC_RELAXED,
+ __MEMORY_SCOPE_DEVICE);
+}
+
+// CHECK-LABEL: define hidden zeroext i1 @fi7c(
+// CHECK: [[TMP0:%.*]] = atomicrmw xchg ptr [[PTR0:%.+]], i8 [[VAL0:.+]] syncscope("workgroup-one-as") monotonic, align 1
+_Bool fi7c(_Bool *c) {
+ return __scoped_atomic_exchange_n(c, 1, __ATOMIC_RELAXED,
+ __MEMORY_SCOPE_WRKGRP);
+}
+
+// CHECK-LABEL: define hidden zeroext i1 @fi7d(
+// CHECK: [[TMP0:%.*]] = atomicrmw xchg ptr [[PTR0:%.+]], i8 [[VAL0:.+]] syncscope("wavefront-one-as") monotonic, align 1
+_Bool fi7d(_Bool *c) {
+ return __scoped_atomic_exchange_n(c, 1, __ATOMIC_RELAXED,
+ __MEMORY_SCOPE_WVFRNT);
+}
+
+// CHECK-LABEL: define hidden zeroext i1 @fi7e(
+// CHECK: [[TMP0:%.*]] = atomicrmw xchg ptr [[PTR0:%.+]], i8 [[VAL0:.+]] syncscope("singlethread-one-as") monotonic, align 1
+_Bool fi7e(_Bool *c) {
+ return __scoped_atomic_exchange_n(c, 1, __ATOMIC_RELAXED,
+ __MEMORY_SCOPE_SINGLE);
+}
clang/test/CodeGen/tbaa.c
@@ -0,0 +1,116 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -no-struct-path-tbaa -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefixes=PATH
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O0 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefix=NO-TBAA
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -relaxed-aliasing -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefix=NO-TBAA
+// Test TBAA metadata generated by front-end.
+//
+// NO-TBAA-NOT: !tbaa
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+
+typedef enum {
+ RED_AUTO_32,
+ GREEN_AUTO_32,
+ BLUE_AUTO_32
+} EnumAuto32;
+
+typedef enum {
+ RED_AUTO_64,
+ GREEN_AUTO_64,
+ BLUE_AUTO_64 = 0x100000000ull
+} EnumAuto64;
+
+typedef enum : uint16_t {
+ RED_16,
+ GREEN_16,
+ BLUE_16
+} Enum16;
+
+typedef enum : uint8_t {
+ RED_8,
+ GREEN_8,
+ BLUE_8
+} Enum8;
+
+uint32_t g0(EnumAuto32 *E, uint32_t *val) {
+// CHECK-LABEL: define{{.*}} i32 @g0(
+// CHECK: store i32 5, ptr %{{.*}}, align 4, !tbaa [[TAG_i32:!.*]]
+// CHECK: store i32 0, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
+// CHECK: load i32, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
+// PATH-LABEL: define{{.*}} i32 @g0(
+// PATH: store i32 5, ptr %{{.*}}, align 4, !tbaa [[TAG_i32:!.*]]
+// PATH: store i32 0, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
+// PATH: load i32, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]]
+ *val = 5;
+ *E = RED_AUTO_32;
+ return *val;
+}
+
+uint64_t g1(EnumAuto64 *E, uint64_t *val) {
+// CHECK-LABEL: define{{.*}} i64 @g1(
+// CHECK: store i64 5, ptr %{{.*}}, align 8, !tbaa [[TAG_i64:!.*]]
+// CHECK: store i64 0, ptr %{{.*}}, align 8, !tbaa [[TAG_long:!.*]]
+// CHECK: load i64, ptr %{{.*}}, align 8, !tbaa [[TAG_i64]]
+// PATH-LABEL: define{{.*}} i64 @g1(
+// PATH: store i64 5, ptr %{{.*}}, align 8, !tbaa [[TAG_i64:!.*]]
+// PATH: store i64 0, ptr %{{.*}}, align 8, !tbaa [[TAG_long:!.*]]
+// PATH: load i64, ptr %{{.*}}, align 8, !tbaa [[TAG_i64]]
+ *val = 5;
+ *E = RED_AUTO_64;
+ return *val;
+}
+
+uint16_t g2(Enum16 *E, uint16_t *val) {
+// CHECK-LABEL: define{{.*}} i16 @g2(
+// CHECK: store i16 5, ptr %{{.*}}, align 2, !tbaa [[TAG_i16:!.*]]
+// CHECK: store i16 0, ptr %{{.*}}, align 2, !tbaa [[TAG_i16]]
+// CHECK: load i16, ptr %{{.*}}, align 2, !tbaa [[TAG_i16]]
+// PATH-LABEL: define{{.*}} i16 @g2(
+// PATH: store i16 5, ptr %{{.*}}, align 2, !tbaa [[TAG_i16:!.*]]
+// PATH: store i16 0, ptr %{{.*}}, align 2, !tbaa [[TAG_i16]]
+// PATH: load i16, ptr %{{.*}}, align 2, !tbaa [[TAG_i16]]
+ *val = 5;
+ *E = RED_16;
+ return *val;
+}
+
+uint8_t g3(Enum8 *E, uint8_t *val) {
+// CHECK-LABEL: define{{.*}} i8 @g3(
+// CHECK: store i8 5, ptr %{{.*}}, align 1, !tbaa [[TAG_i8:!.*]]
+// CHECK: store i8 0, ptr %{{.*}}, align 1, !tbaa [[TAG_i8]]
+// CHECK: load i8, ptr %{{.*}}, align 1, !tbaa [[TAG_i8]]
+// PATH-LABEL: define{{.*}} i8 @g3(
+// PATH: store i8 5, ptr %{{.*}}, align 1, !tbaa [[TAG_i8:!.*]]
+// PATH: store i8 0, ptr %{{.*}}, align 1, !tbaa [[TAG_i8]]
+// PATH: load i8, ptr %{{.*}}, align 1, !tbaa [[TAG_i8]]
+ *val = 5;
+ *E = RED_8;
+ return *val;
+}
+
+// CHECK: [[TYPE_char:!.*]] = !{!"omnipotent char", [[TAG_c_tbaa:!.*]],
+// CHECK: [[TAG_c_tbaa]] = !{!"Simple C/C++ TBAA"}
+// CHECK: [[TAG_i32]] = !{[[TYPE_i32:!.*]], [[TYPE_i32]], i64 0}
+// CHECK: [[TYPE_i32]] = !{!"int", [[TYPE_char]],
+// CHECK: [[TAG_i64]] = !{[[TYPE_i64:!.*]], [[TYPE_i64]], i64 0}
+// CHECK: [[TYPE_i64]] = !{!"long long", [[TYPE_char]],
+// CHECK: [[TAG_long]] = !{[[TYPE_long:!.*]], [[TYPE_long]], i64 0}
+// CHECK: [[TYPE_long]] = !{!"long", [[TYPE_char]],
+// CHECK: [[TAG_i16]] = !{[[TYPE_i16:!.*]], [[TYPE_i16]], i64 0}
+// CHECK: [[TYPE_i16]] = !{!"short", [[TYPE_char]],
+// CHECK: [[TAG_i8]] = !{[[TYPE_i8:!.*]], [[TYPE_char]], i64 0}
+
+// PATH: [[TYPE_char:!.*]] = !{!"omnipotent char", [[TAG_c_tbaa:!.*]],
+// PATH: [[TAG_c_tbaa]] = !{!"Simple C/C++ TBAA"}
+// PATH: [[TAG_i32]] = !{[[TYPE_i32:!.*]], [[TYPE_i32]], i64 0}
+// PATH: [[TYPE_i32]] = !{!"int", [[TYPE_char]],
+// PATH: [[TAG_i64]] = !{[[TYPE_i64:!.*]], [[TYPE_i64]], i64 0}
+// PATH: [[TYPE_i64]] = !{!"long long", [[TYPE_char]],
+// PATH: [[TAG_long]] = !{[[TYPE_long:!.*]], [[TYPE_long]], i64 0}
+// PATH: [[TYPE_long]] = !{!"long", [[TYPE_char]],
+// PATH: [[TAG_i16]] = !{[[TYPE_i16:!.*]], [[TYPE_i16]], i64 0}
+// PATH: [[TYPE_i16]] = !{!"short", [[TYPE_char]],
+// PATH: [[TAG_i8]] = !{[[TYPE_i8:!.*]], [[TYPE_char]], i64 0}
clang/test/CodeGenCUDA/offloading-entries.cu
@@ -17,31 +17,47 @@
//. //.
// CUDA: @.omp_offloading.entry_name = internal unnamed_addr constant [8 x i8] c"_Z3foov\00" // CUDA: @.omp_offloading.entry_name = internal unnamed_addr constant [8 x i8] c"_Z3foov\00"
// CUDA: @.omp_offloading.entry._Z3foov = weak constant %struct.__tgt_offload_entry { ptr @_Z18__device_stub__foov, ptr @.omp_offloading.entry_name, i64 0, i32 0, i32 0 }, section "cuda_offloading_entries", align 1 // CUDA: @.omp_offloading.entry._Z3foov = weak constant %struct.__tgt_offload_entry { ptr @_Z18__device_stub__foov, ptr @.omp_offloading.entry_name, i64 0, i32 0, i32 0 }, section "cuda_offloading_entries", align 1
-// CUDA: @.omp_offloading.entry_name.1 = internal unnamed_addr constant [8 x i8] c"_Z3barv\00"+// CUDA: @.omp_offloading.entry_name.1 = internal unnamed_addr constant [11 x i8] c"_Z6kernelv\00"
-// CUDA: @.omp_offloading.entry._Z3barv = weak constant %struct.__tgt_offload_entry { ptr @_Z18__device_stub__barv, ptr @.omp_offloading.entry_name.1, i64 0, i32 0, i32 0 }, section "cuda_offloading_entries", align 1+// CUDA: @.omp_offloading.entry._Z6kernelv = weak constant %struct.__tgt_offload_entry { ptr @_Z21__device_stub__kernelv, ptr @.omp_offloading.entry_name.1, i64 0, i32 0, i32 0 }, section "cuda_offloading_entries", align 1
-// CUDA: @.omp_offloading.entry_name.2 = internal unnamed_addr constant [2 x i8] c"x\00"+// CUDA: @.omp_offloading.entry_name.2 = internal unnamed_addr constant [4 x i8] c"var\00"
-// CUDA: @.omp_offloading.entry.x = weak constant %struct.__tgt_offload_entry { ptr @x, ptr @.omp_offloading.entry_name.2, i64 4, i32 0, i32 0 }, section "cuda_offloading_entries", align 1+// CUDA: @.omp_offloading.entry.var = weak constant %struct.__tgt_offload_entry { ptr @var, ptr @.omp_offloading.entry_name.2, i64 4, i32 0, i32 0 }, section "cuda_offloading_entries", align 1
+// CUDA: @.omp_offloading.entry_name.3 = internal unnamed_addr constant [5 x i8] c"surf\00"
+// CUDA: @.omp_offloading.entry.surf = weak constant %struct.__tgt_offload_entry { ptr @surf, ptr @.omp_offloading.entry_name.3, i64 4, i32 2, i32 1 }, section "cuda_offloading_entries", align 1
+// CUDA: @.omp_offloading.entry_name.4 = internal unnamed_addr constant [4 x i8] c"tex\00"
+// CUDA: @.omp_offloading.entry.tex = weak constant %struct.__tgt_offload_entry { ptr @tex, ptr @.omp_offloading.entry_name.4, i64 4, i32 3, i32 1 }, section "cuda_offloading_entries", align 1
//. //.
// HIP: @.omp_offloading.entry_name = internal unnamed_addr constant [8 x i8] c"_Z3foov\00" // HIP: @.omp_offloading.entry_name = internal unnamed_addr constant [8 x i8] c"_Z3foov\00"
// HIP: @.omp_offloading.entry._Z3foov = weak constant %struct.__tgt_offload_entry { ptr @_Z3foov, ptr @.omp_offloading.entry_name, i64 0, i32 0, i32 0 }, section "hip_offloading_entries", align 1 // HIP: @.omp_offloading.entry._Z3foov = weak constant %struct.__tgt_offload_entry { ptr @_Z3foov, ptr @.omp_offloading.entry_name, i64 0, i32 0, i32 0 }, section "hip_offloading_entries", align 1
-// HIP: @.omp_offloading.entry_name.1 = internal unnamed_addr constant [8 x i8] c"_Z3barv\00"+// HIP: @.omp_offloading.entry_name.1 = internal unnamed_addr constant [11 x i8] c"_Z6kernelv\00"
-// HIP: @.omp_offloading.entry._Z3barv = weak constant %struct.__tgt_offload_entry { ptr @_Z3barv, ptr @.omp_offloading.entry_name.1, i64 0, i32 0, i32 0 }, section "hip_offloading_entries", align 1+// HIP: @.omp_offloading.entry._Z6kernelv = weak constant %struct.__tgt_offload_entry { ptr @_Z6kernelv, ptr @.omp_offloading.entry_name.1, i64 0, i32 0, i32 0 }, section "hip_offloading_entries", align 1
-// HIP: @.omp_offloading.entry_name.2 = internal unnamed_addr constant [2 x i8] c"x\00"+// HIP: @.omp_offloading.entry_name.2 = internal unnamed_addr constant [4 x i8] c"var\00"
-// HIP: @.omp_offloading.entry.x = weak constant %struct.__tgt_offload_entry { ptr @x, ptr @.omp_offloading.entry_name.2, i64 4, i32 0, i32 0 }, section "hip_offloading_entries", align 1+// HIP: @.omp_offloading.entry.var = weak constant %struct.__tgt_offload_entry { ptr @var, ptr @.omp_offloading.entry_name.2, i64 4, i32 0, i32 0 }, section "hip_offloading_entries", align 1
+// HIP: @.omp_offloading.entry_name.3 = internal unnamed_addr constant [5 x i8] c"surf\00"
+// HIP: @.omp_offloading.entry.surf = weak constant %struct.__tgt_offload_entry { ptr @surf, ptr @.omp_offloading.entry_name.3, i64 4, i32 2, i32 1 }, section "hip_offloading_entries", align 1
+// HIP: @.omp_offloading.entry_name.4 = internal unnamed_addr constant [4 x i8] c"tex\00"
+// HIP: @.omp_offloading.entry.tex = weak constant %struct.__tgt_offload_entry { ptr @tex, ptr @.omp_offloading.entry_name.4, i64 4, i32 3, i32 1 }, section "hip_offloading_entries", align 1
//. //.
// CUDA-COFF: @.omp_offloading.entry_name = internal unnamed_addr constant [8 x i8] c"_Z3foov\00" // CUDA-COFF: @.omp_offloading.entry_name = internal unnamed_addr constant [8 x i8] c"_Z3foov\00"
// CUDA-COFF: @.omp_offloading.entry._Z3foov = weak constant %struct.__tgt_offload_entry { ptr @_Z18__device_stub__foov, ptr @.omp_offloading.entry_name, i64 0, i32 0, i32 0 }, section "cuda_offloading_entries$OE", align 1 // CUDA-COFF: @.omp_offloading.entry._Z3foov = weak constant %struct.__tgt_offload_entry { ptr @_Z18__device_stub__foov, ptr @.omp_offloading.entry_name, i64 0, i32 0, i32 0 }, section "cuda_offloading_entries$OE", align 1
-// CUDA-COFF: @.omp_offloading.entry_name.1 = internal unnamed_addr constant [8 x i8] c"_Z3barv\00"+// CUDA-COFF: @.omp_offloading.entry_name.1 = internal unnamed_addr constant [11 x i8] c"_Z6kernelv\00"
-// CUDA-COFF: @.omp_offloading.entry._Z3barv = weak constant %struct.__tgt_offload_entry { ptr @_Z18__device_stub__barv, ptr @.omp_offloading.entry_name.1, i64 0, i32 0, i32 0 }, section "cuda_offloading_entries$OE", align 1+// CUDA-COFF: @.omp_offloading.entry._Z6kernelv = weak constant %struct.__tgt_offload_entry { ptr @_Z21__device_stub__kernelv, ptr @.omp_offloading.entry_name.1, i64 0, i32 0, i32 0 }, section "cuda_offloading_entries$OE", align 1
-// CUDA-COFF: @.omp_offloading.entry_name.2 = internal unnamed_addr constant [2 x i8] c"x\00"+// CUDA-COFF: @.omp_offloading.entry_name.2 = internal unnamed_addr constant [4 x i8] c"var\00"
-// CUDA-COFF: @.omp_offloading.entry.x = weak constant %struct.__tgt_offload_entry { ptr @x, ptr @.omp_offloading.entry_name.2, i64 4, i32 0, i32 0 }, section "cuda_offloading_entries$OE", align 1+// CUDA-COFF: @.omp_offloading.entry.var = weak constant %struct.__tgt_offload_entry { ptr @var, ptr @.omp_offloading.entry_name.2, i64 4, i32 0, i32 0 }, section "cuda_offloading_entries$OE", align 1
+// CUDA-COFF: @.omp_offloading.entry_name.3 = internal unnamed_addr constant [5 x i8] c"surf\00"
+// CUDA-COFF: @.omp_offloading.entry.surf = weak constant %struct.__tgt_offload_entry { ptr @surf, ptr @.omp_offloading.entry_name.3, i64 4, i32 2, i32 1 }, section "cuda_offloading_entries$OE", align 1
+// CUDA-COFF: @.omp_offloading.entry_name.4 = internal unnamed_addr constant [4 x i8] c"tex\00"
+// CUDA-COFF: @.omp_offloading.entry.tex = weak constant %struct.__tgt_offload_entry { ptr @tex, ptr @.omp_offloading.entry_name.4, i64 4, i32 3, i32 1 }, section "cuda_offloading_entries$OE", align 1
//. //.
// HIP-COFF: @.omp_offloading.entry_name = internal unnamed_addr constant [8 x i8] c"_Z3foov\00" // HIP-COFF: @.omp_offloading.entry_name = internal unnamed_addr constant [8 x i8] c"_Z3foov\00"
// HIP-COFF: @.omp_offloading.entry._Z3foov = weak constant %struct.__tgt_offload_entry { ptr @_Z3foov, ptr @.omp_offloading.entry_name, i64 0, i32 0, i32 0 }, section "hip_offloading_entries$OE", align 1 // HIP-COFF: @.omp_offloading.entry._Z3foov = weak constant %struct.__tgt_offload_entry { ptr @_Z3foov, ptr @.omp_offloading.entry_name, i64 0, i32 0, i32 0 }, section "hip_offloading_entries$OE", align 1
-// HIP-COFF: @.omp_offloading.entry_name.1 = internal unnamed_addr constant [8 x i8] c"_Z3barv\00"+// HIP-COFF: @.omp_offloading.entry_name.1 = internal unnamed_addr constant [11 x i8] c"_Z6kernelv\00"
-// HIP-COFF: @.omp_offloading.entry._Z3barv = weak constant %struct.__tgt_offload_entry { ptr @_Z3barv, ptr @.omp_offloading.entry_name.1, i64 0, i32 0, i32 0 }, section "hip_offloading_entries$OE", align 1+// HIP-COFF: @.omp_offloading.entry._Z6kernelv = weak constant %struct.__tgt_offload_entry { ptr @_Z6kernelv, ptr @.omp_offloading.entry_name.1, i64 0, i32 0, i32 0 }, section "hip_offloading_entries$OE", align 1
-// HIP-COFF: @.omp_offloading.entry_name.2 = internal unnamed_addr constant [2 x i8] c"x\00"+// HIP-COFF: @.omp_offloading.entry_name.2 = internal unnamed_addr constant [4 x i8] c"var\00"
-// HIP-COFF: @.omp_offloading.entry.x = weak constant %struct.__tgt_offload_entry { ptr @x, ptr @.omp_offloading.entry_name.2, i64 4, i32 0, i32 0 }, section "hip_offloading_entries$OE", align 1+// HIP-COFF: @.omp_offloading.entry.var = weak constant %struct.__tgt_offload_entry { ptr @var, ptr @.omp_offloading.entry_name.2, i64 4, i32 0, i32 0 }, section "hip_offloading_entries$OE", align 1
+// HIP-COFF: @.omp_offloading.entry_name.3 = internal unnamed_addr constant [5 x i8] c"surf\00"
+// HIP-COFF: @.omp_offloading.entry.surf = weak constant %struct.__tgt_offload_entry { ptr @surf, ptr @.omp_offloading.entry_name.3, i64 4, i32 2, i32 1 }, section "hip_offloading_entries$OE", align 1
+// HIP-COFF: @.omp_offloading.entry_name.4 = internal unnamed_addr constant [4 x i8] c"tex\00"
+// HIP-COFF: @.omp_offloading.entry.tex = weak constant %struct.__tgt_offload_entry { ptr @tex, ptr @.omp_offloading.entry_name.4, i64 4, i32 3, i32 1 }, section "hip_offloading_entries$OE", align 1
//. //.
// CUDA-LABEL: @_Z18__device_stub__foov( // CUDA-LABEL: @_Z18__device_stub__foov(
// CUDA-NEXT: entry: // CUDA-NEXT: entry:
@@ -72,34 +88,52 @@
// HIP-COFF-NEXT: ret void // HIP-COFF-NEXT: ret void
// //
__global__ void foo() {} __global__ void foo() {}
+__device__ int var = 1;
+const __device__ int constant = 1;
+extern __device__ int external;
-// CUDA-LABEL: @_Z18__device_stub__barv(+// CUDA-LABEL: @_Z21__device_stub__kernelv(
// CUDA-NEXT: entry: // CUDA-NEXT: entry:
-// CUDA-NEXT: [[TMP0:%.*]] = call i32 @cudaLaunch(ptr @_Z18__device_stub__barv)+// CUDA-NEXT: [[TMP0:%.*]] = call i32 @cudaLaunch(ptr @_Z21__device_stub__kernelv)
// CUDA-NEXT: br label [[SETUP_END:%.*]] // CUDA-NEXT: br label [[SETUP_END:%.*]]
// CUDA: setup.end: // CUDA: setup.end:
// CUDA-NEXT: ret void // CUDA-NEXT: ret void
// //
-// HIP-LABEL: @_Z18__device_stub__barv(+// HIP-LABEL: @_Z21__device_stub__kernelv(
// HIP-NEXT: entry: // HIP-NEXT: entry:
-// HIP-NEXT: [[TMP0:%.*]] = call i32 @hipLaunchByPtr(ptr @_Z3barv)+// HIP-NEXT: [[TMP0:%.*]] = call i32 @hipLaunchByPtr(ptr @_Z6kernelv)
// HIP-NEXT: br label [[SETUP_END:%.*]] // HIP-NEXT: br label [[SETUP_END:%.*]]
// HIP: setup.end: // HIP: setup.end:
// HIP-NEXT: ret void // HIP-NEXT: ret void
// //
-// CUDA-COFF-LABEL: @_Z18__device_stub__barv(+// CUDA-COFF-LABEL: @_Z21__device_stub__kernelv(
// CUDA-COFF-NEXT: entry: // CUDA-COFF-NEXT: entry:
-// CUDA-COFF-NEXT: [[TMP0:%.*]] = call i32 @cudaLaunch(ptr @_Z18__device_stub__barv)+// CUDA-COFF-NEXT: [[TMP0:%.*]] = call i32 @cudaLaunch(ptr @_Z21__device_stub__kernelv)
// CUDA-COFF-NEXT: br label [[SETUP_END:%.*]] // CUDA-COFF-NEXT: br label [[SETUP_END:%.*]]
// CUDA-COFF: setup.end: // CUDA-COFF: setup.end:
// CUDA-COFF-NEXT: ret void // CUDA-COFF-NEXT: ret void
// //
-// HIP-COFF-LABEL: @_Z18__device_stub__barv(+// HIP-COFF-LABEL: @_Z21__device_stub__kernelv(
// HIP-COFF-NEXT: entry: // HIP-COFF-NEXT: entry:
-// HIP-COFF-NEXT: [[TMP0:%.*]] = call i32 @hipLaunchByPtr(ptr @_Z3barv)+// HIP-COFF-NEXT: [[TMP0:%.*]] = call i32 @hipLaunchByPtr(ptr @_Z6kernelv)
// HIP-COFF-NEXT: br label [[SETUP_END:%.*]] // HIP-COFF-NEXT: br label [[SETUP_END:%.*]]
// HIP-COFF: setup.end: // HIP-COFF: setup.end:
// HIP-COFF-NEXT: ret void // HIP-COFF-NEXT: ret void
// //
-__global__ void bar() {}+__global__ void kernel() { external = 1; }
-__device__ int x = 1;+
+struct surfaceReference { int desc; };
+
+template <typename T, int dim = 1>
+struct __attribute__((device_builtin_surface_type)) surface : public surfaceReference {};
+
+surface<void> surf;
+
+struct textureReference {
+ int desc;
+};
+
+template <typename T, int dim = 1, int mode = 0>
+struct __attribute__((device_builtin_texture_type)) texture : public textureReference {};
+
+texture<void> tex;
clang/test/Driver/aarch64-outliner.c
@@ -1,7 +1,9 @@
// REQUIRES: aarch64-registered-target // REQUIRES: aarch64-registered-target
// RUN: %clang --target=aarch64 -moutline -S %s -### 2>&1 | FileCheck %s -check-prefix=ON // RUN: %clang --target=aarch64 -moutline -S %s -### 2>&1 | FileCheck %s -check-prefix=ON
+// RUN: %clang --target=aarch64_be -moutline -S %s -### 2>&1 | FileCheck %s -check-prefix=ON
// ON: "-mllvm" "-enable-machine-outliner" // ON: "-mllvm" "-enable-machine-outliner"
// RUN: %clang --target=aarch64 -moutline -mno-outline -S %s -### 2>&1 | FileCheck %s -check-prefix=OFF // RUN: %clang --target=aarch64 -moutline -mno-outline -S %s -### 2>&1 | FileCheck %s -check-prefix=OFF
+// RUN: %clang --target=aarch64_be -moutline -mno-outline -S %s -### 2>&1 | FileCheck %s -check-prefix=OFF
// OFF: "-mllvm" "-enable-machine-outliner=never" // OFF: "-mllvm" "-enable-machine-outliner=never"
// RUN: %clang --target=x86_64 -moutline -S %s -### 2>&1 | FileCheck %s -check-prefix=WARN // RUN: %clang --target=x86_64 -moutline -S %s -### 2>&1 | FileCheck %s -check-prefix=WARN
// WARN: warning: 'x86_64' does not support '-moutline'; flag ignored [-Woption-ignored] // WARN: warning: 'x86_64' does not support '-moutline'; flag ignored [-Woption-ignored]
clang/test/Driver/arm-cortex-cpus-2.c
@@ -562,6 +562,9 @@
// RUN: %clang -target arm -mcpu=cortex-m85 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-M85 %s // RUN: %clang -target arm -mcpu=cortex-m85 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-M85 %s
// CHECK-CORTEX-M85: "-cc1"{{.*}} "-triple" "thumbv8.1m.main-{{.*}} "-target-cpu" "cortex-m85" // CHECK-CORTEX-M85: "-cc1"{{.*}} "-triple" "thumbv8.1m.main-{{.*}} "-target-cpu" "cortex-m85"
+// RUN: %clang -target arm -mcpu=cortex-m52 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-M52 %s
+// CHECK-CORTEX-M52: "-cc1"{{.*}} "-triple" "thumbv8.1m.main-{{.*}} "-target-cpu" "cortex-m52"
+
// RUN: %clang -target arm -mcpu=neoverse-n2 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NEOVERSE-N2 %s // RUN: %clang -target arm -mcpu=neoverse-n2 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-NEOVERSE-N2 %s
// CHECK-NEOVERSE-N2: "-cc1"{{.*}} "-triple" "armv8.5a-{{.*}}" "-target-cpu" "neoverse-n2" // CHECK-NEOVERSE-N2: "-cc1"{{.*}} "-triple" "armv8.5a-{{.*}}" "-target-cpu" "neoverse-n2"
clang/test/Driver/clang-offload-bundler-zlib.c
@@ -55,14 +55,15 @@
// Check unbundling archive. // Check unbundling archive.
// //
// RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \ // RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \
-// RUN: -input=%t.tgt1 -input=%t.tgt2 -output=%T/hip_bundle1.bc -compress+// RUN: -input=%t.tgt1 -input=%t.tgt2 -output=%t.hip_bundle1.bc -compress
// RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \ // RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \
-// RUN: -input=%t.tgt1 -input=%t.tgt2 -output=%T/hip_bundle2.bc -compress+// RUN: -input=%t.tgt1 -input=%t.tgt2 -output=%t.hip_bundle2.bc -compress
-// RUN: llvm-ar cr %T/hip_archive.a %T/hip_bundle1.bc %T/hip_bundle2.bc+// RUN: rm -f %t.hip_archive.a
+// RUN: llvm-ar cr %t.hip_archive.a %t.hip_bundle1.bc %t.hip_bundle2.bc
// RUN: clang-offload-bundler -unbundle -type=a -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \ // RUN: clang-offload-bundler -unbundle -type=a -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \
-// RUN: -output=%T/hip_900.a -output=%T/hip_906.a -input=%T/hip_archive.a+// RUN: -output=%t.hip_900.a -output=%t.hip_906.a -input=%t.hip_archive.a
-// RUN: llvm-ar t %T/hip_900.a | FileCheck -check-prefix=HIP-AR-900 %s+// RUN: llvm-ar t %t.hip_900.a | FileCheck -check-prefix=HIP-AR-900 %s
-// RUN: llvm-ar t %T/hip_906.a | FileCheck -check-prefix=HIP-AR-906 %s+// RUN: llvm-ar t %t.hip_906.a | FileCheck -check-prefix=HIP-AR-906 %s
// HIP-AR-900-DAG: hip_bundle1-hip-amdgcn-amd-amdhsa--gfx900 // HIP-AR-900-DAG: hip_bundle1-hip-amdgcn-amd-amdhsa--gfx900
// HIP-AR-900-DAG: hip_bundle2-hip-amdgcn-amd-amdhsa--gfx900 // HIP-AR-900-DAG: hip_bundle2-hip-amdgcn-amd-amdhsa--gfx900
// HIP-AR-906-DAG: hip_bundle1-hip-amdgcn-amd-amdhsa--gfx906 // HIP-AR-906-DAG: hip_bundle1-hip-amdgcn-amd-amdhsa--gfx906
clang/test/Driver/clang-offload-bundler-zstd.c
@@ -48,18 +48,18 @@
// RUN: diff %t.tgt1 %t.res.tgt1 // RUN: diff %t.tgt1 %t.res.tgt1
// RUN: diff %t.tgt2 %t.res.tgt2 // RUN: diff %t.tgt2 %t.res.tgt2
-//
// Check unbundling archive. // Check unbundling archive.
// //
// RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \ // RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \
-// RUN: -input=%t.tgt1 -input=%t.tgt2 -output=%T/hip_bundle1.bc -compress+// RUN: -input=%t.tgt1 -input=%t.tgt2 -output=%t.hip_bundle1.bc -compress
// RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \ // RUN: clang-offload-bundler -type=bc -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \
-// RUN: -input=%t.tgt1 -input=%t.tgt2 -output=%T/hip_bundle2.bc -compress+// RUN: -input=%t.tgt1 -input=%t.tgt2 -output=%t.hip_bundle2.bc -compress
-// RUN: llvm-ar cr %T/hip_archive.a %T/hip_bundle1.bc %T/hip_bundle2.bc+// RUN: rm -f %t.hip_archive.a
+// RUN: llvm-ar cr %t.hip_archive.a %t.hip_bundle1.bc %t.hip_bundle2.bc
// RUN: clang-offload-bundler -unbundle -type=a -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \ // RUN: clang-offload-bundler -unbundle -type=a -targets=hip-amdgcn-amd-amdhsa--gfx900,hip-amdgcn-amd-amdhsa--gfx906 \
-// RUN: -output=%T/hip_900.a -output=%T/hip_906.a -input=%T/hip_archive.a+// RUN: -output=%t.hip_900.a -output=%t.hip_906.a -input=%t.hip_archive.a
-// RUN: llvm-ar t %T/hip_900.a | FileCheck -check-prefix=HIP-AR-900 %s+// RUN: llvm-ar t %t.hip_900.a | FileCheck -check-prefix=HIP-AR-900 %s
-// RUN: llvm-ar t %T/hip_906.a | FileCheck -check-prefix=HIP-AR-906 %s+// RUN: llvm-ar t %t.hip_906.a | FileCheck -check-prefix=HIP-AR-906 %s
// HIP-AR-900-DAG: hip_bundle1-hip-amdgcn-amd-amdhsa--gfx900 // HIP-AR-900-DAG: hip_bundle1-hip-amdgcn-amd-amdhsa--gfx900
// HIP-AR-900-DAG: hip_bundle2-hip-amdgcn-amd-amdhsa--gfx900 // HIP-AR-900-DAG: hip_bundle2-hip-amdgcn-amd-amdhsa--gfx900
// HIP-AR-906-DAG: hip_bundle1-hip-amdgcn-amd-amdhsa--gfx906 // HIP-AR-906-DAG: hip_bundle1-hip-amdgcn-amd-amdhsa--gfx906
clang/test/Driver/fdefine-target-os-macros.c
@@ -0,0 +1,250 @@
+// RUN: %clang -### --target=arm64-apple-darwin %s 2>&1 | FileCheck %s --check-prefix=DARWIN-DEFAULT
+// DARWIN-DEFAULT-NOT: "-fdefine-target-os-macros"
+
+// RUN: %clang -### --target=arm-none-linux-gnu %s 2>&1 | FileCheck %s --check-prefix=NON-DARWIN-DEFAULT
+// RUN: %clang -### --target=x86_64-pc-win32 %s 2>&1 | FileCheck %s --check-prefix=NON-DARWIN-DEFAULT
+// NON-DARWIN-DEFAULT-NOT: "-fdefine-target-os-macros"
+
+// RUN: %clang -dM -E --target=arm64-apple-macos \
+// RUN: -fdefine-target-os-macros %s 2>&1 \
+// RUN: | FileCheck %s -DMAC=1 \
+// RUN: -DOSX=1 \
+// RUN: -DIPHONE=0 \
+// RUN: -DIOS=0 \
+// RUN: -DTV=0 \
+// RUN: -DWATCH=0 \
+// RUN: -DDRIVERKIT=0 \
+// RUN: -DMACCATALYST=0 \
+// RUN: -DEMBEDDED=0 \
+// RUN: -DSIMULATOR=0 \
+// RUN: -DWINDOWS=0 \
+// RUN: -DLINUX=0 \
+// RUN: -DUNIX=0
+
+// RUN: %clang -dM -E --target=arm64-apple-ios \
+// RUN: -fdefine-target-os-macros %s 2>&1 \
+// RUN: | FileCheck %s -DMAC=1 \
+// RUN: -DOSX=0 \
+// RUN: -DIPHONE=1 \
+// RUN: -DIOS=1 \
+// RUN: -DTV=0 \
+// RUN: -DWATCH=0 \
+// RUN: -DDRIVERKIT=0 \
+// RUN: -DMACCATALYST=0 \
+// RUN: -DEMBEDDED=1 \
+// RUN: -DSIMULATOR=0 \
+// RUN: -DWINDOWS=0 \
+// RUN: -DLINUX=0 \
+// RUN: -DUNIX=0
+
+// RUN: %clang -dM -E --target=arm64-apple-ios-macabi \
+// RUN: -fdefine-target-os-macros %s 2>&1 \
+// RUN: | FileCheck %s -DMAC=1 \
+// RUN: -DOSX=0 \
+// RUN: -DIPHONE=1 \
+// RUN: -DIOS=1 \
+// RUN: -DTV=0 \
+// RUN: -DWATCH=0 \
+// RUN: -DDRIVERKIT=0 \
+// RUN: -DMACCATALYST=1 \
+// RUN: -DEMBEDDED=0 \
+// RUN: -DSIMULATOR=0 \
+// RUN: -DWINDOWS=0 \
+// RUN: -DLINUX=0 \
+// RUN: -DUNIX=0
+
+// RUN: %clang -dM -E --target=arm64-apple-ios-simulator \
+// RUN: -fdefine-target-os-macros %s 2>&1 \
+// RUN: | FileCheck %s -DMAC=1 \
+// RUN: -DOSX=0 \
+// RUN: -DIPHONE=1 \
+// RUN: -DIOS=1 \
+// RUN: -DTV=0 \
+// RUN: -DWATCH=0 \
+// RUN: -DDRIVERKIT=0 \
+// RUN: -DMACCATALYST=0 \
+// RUN: -DEMBEDDED=0 \
+// RUN: -DSIMULATOR=1 \
+// RUN: -DWINDOWS=0 \
+// RUN: -DLINUX=0 \
+// RUN: -DUNIX=0
+
+// RUN: %clang -dM -E --target=arm64-apple-tvos \
+// RUN: -fdefine-target-os-macros %s 2>&1 \
+// RUN: | FileCheck %s -DMAC=1 \
+// RUN: -DOSX=0 \
+// RUN: -DIPHONE=1 \
+// RUN: -DIOS=0 \
+// RUN: -DTV=1 \
+// RUN: -DWATCH=0 \
+// RUN: -DDRIVERKIT=0 \
+// RUN: -DMACCATALYST=0 \
+// RUN: -DEMBEDDED=1 \
+// RUN: -DSIMULATOR=0 \
+// RUN: -DWINDOWS=0 \
+// RUN: -DLINUX=0 \
+// RUN: -DUNIX=0
+
+// RUN: %clang -dM -E --target=arm64-apple-tvos-simulator \
+// RUN: -fdefine-target-os-macros %s 2>&1 \
+// RUN: | FileCheck %s -DMAC=1 \
+// RUN: -DOSX=0 \
+// RUN: -DIPHONE=1 \
+// RUN: -DIOS=0 \
+// RUN: -DTV=1 \
+// RUN: -DWATCH=0 \
+// RUN: -DDRIVERKIT=0 \
+// RUN: -DMACCATALYST=0 \
+// RUN: -DEMBEDDED=0 \
+// RUN: -DSIMULATOR=1 \
+// RUN: -DWINDOWS=0 \
+// RUN: -DLINUX=0 \
+// RUN: -DUNIX=0
+
+// RUN: %clang -dM -E --target=arm64-apple-watchos \
+// RUN: -fdefine-target-os-macros %s 2>&1 \
+// RUN: | FileCheck %s -DMAC=1 \
+// RUN: -DOSX=0 \
+// RUN: -DIPHONE=1 \
+// RUN: -DIOS=0 \
+// RUN: -DTV=0 \
+// RUN: -DWATCH=1 \
+// RUN: -DDRIVERKIT=0 \
+// RUN: -DMACCATALYST=0 \
+// RUN: -DEMBEDDED=1 \
+// RUN: -DSIMULATOR=0 \
+// RUN: -DWINDOWS=0 \
+// RUN: -DLINUX=0 \
+// RUN: -DUNIX=0
+
+// RUN: %clang -dM -E --target=arm64-apple-watchos-simulator \
+// RUN: -fdefine-target-os-macros %s 2>&1 \
+// RUN: | FileCheck %s -DMAC=1 \
+// RUN: -DOSX=0 \
+// RUN: -DIPHONE=1 \
+// RUN: -DIOS=0 \
+// RUN: -DTV=0 \
+// RUN: -DWATCH=1 \
+// RUN: -DDRIVERKIT=0 \
+// RUN: -DMACCATALYST=0 \
+// RUN: -DEMBEDDED=0 \
+// RUN: -DSIMULATOR=1 \
+// RUN: -DWINDOWS=0 \
+// RUN: -DLINUX=0 \
+// RUN: -DUNIX=0
+
+// RUN: %clang -dM -E --target=arm64-apple-driverkit \
+// RUN: -fdefine-target-os-macros %s 2>&1 \
+// RUN: | FileCheck %s -DMAC=1 \
+// RUN: -DOSX=0 \
+// RUN: -DIPHONE=0 \
+// RUN: -DIOS=0 \
+// RUN: -DTV=0 \
+// RUN: -DWATCH=0 \
+// RUN: -DDRIVERKIT=1 \
+// RUN: -DMACCATALYST=0 \
+// RUN: -DEMBEDDED=0 \
+// RUN: -DSIMULATOR=0 \
+// RUN: -DWINDOWS=0 \
+// RUN: -DLINUX=0 \
+// RUN: -DUNIX=0
+
+// RUN: %clang -dM -E --target=x86_64-pc-linux-gnu \
+// RUN: -fdefine-target-os-macros %s 2>&1 \
+// RUN: | FileCheck %s -DMAC=0 \
+// RUN: -DOSX=0 \
+// RUN: -DIPHONE=0 \
+// RUN: -DIOS=0 \
+// RUN: -DTV=0 \
+// RUN: -DWATCH=0 \
+// RUN: -DDRIVERKIT=0 \
+// RUN: -DMACCATALYST=0 \
+// RUN: -DEMBEDDED=0 \
+// RUN: -DSIMULATOR=0 \
+// RUN: -DWINDOWS=0 \
+// RUN: -DLINUX=1 \
+// RUN: -DUNIX=0
+
+// RUN: %clang -dM -E --target=x86_64-pc-win32 \
+// RUN: -fdefine-target-os-macros %s 2>&1 \
+// RUN: | FileCheck %s -DMAC=0 \
+// RUN: -DOSX=0 \
+// RUN: -DIPHONE=0 \
+// RUN: -DIOS=0 \
+// RUN: -DTV=0 \
+// RUN: -DWATCH=0 \
+// RUN: -DDRIVERKIT=0 \
+// RUN: -DMACCATALYST=0 \
+// RUN: -DEMBEDDED=0 \
+// RUN: -DSIMULATOR=0 \
+// RUN: -DWINDOWS=1 \
+// RUN: -DLINUX=0 \
+// RUN: -DUNIX=0
+
+// RUN: %clang -dM -E --target=x86_64-pc-windows-gnu \
+// RUN: -fdefine-target-os-macros %s 2>&1 \
+// RUN: | FileCheck %s -DMAC=0 \
+// RUN: -DOSX=0 \
+// RUN: -DIPHONE=0 \
+// RUN: -DIOS=0 \
+// RUN: -DTV=0 \
+// RUN: -DWATCH=0 \
+// RUN: -DDRIVERKIT=0 \
+// RUN: -DMACCATALYST=0 \
+// RUN: -DEMBEDDED=0 \
+// RUN: -DSIMULATOR=0 \
+// RUN: -DWINDOWS=1 \
+// RUN: -DLINUX=0 \
+// RUN: -DUNIX=0
+
+// RUN: %clang -dM -E --target=sparc-none-solaris \
+// RUN: -fdefine-target-os-macros %s 2>&1 \
+// RUN: | FileCheck %s -DMAC=0 \
+// RUN: -DOSX=0 \
+// RUN: -DIPHONE=0 \
+// RUN: -DIOS=0 \
+// RUN: -DTV=0 \
+// RUN: -DWATCH=0 \
+// RUN: -DDRIVERKIT=0 \
+// RUN: -DMACCATALYST=0 \
+// RUN: -DEMBEDDED=0 \
+// RUN: -DSIMULATOR=0 \
+// RUN: -DWINDOWS=0 \
+// RUN: -DLINUX=0 \
+// RUN: -DUNIX=1
+
+// RUN: %clang -dM -E --target=arm64-apple-macos \
+// RUN: -fno-define-target-os-macros %s 2>&1 \
+// RUN: | FileCheck %s --check-prefix=NEG
+
+// RUN: %clang -dM -E --target=arm64-apple-macos \
+// RUN: -fdefine-target-os-macros \
+// RUN: -fno-define-target-os-macros %s 2>&1 \
+// RUN: | FileCheck %s --check-prefix=NEG
+
+// RUN: %clang -dM -E --target=x86_64-pc-windows \
+// RUN: -fdefine-target-os-macros \
+// RUN: -fno-define-target-os-macros %s 2>&1 \
+// RUN: | FileCheck %s --check-prefix=NEG
+
+// NEG-NOT: #define TARGET_OS_
+
+// CHECK-DAG: #define TARGET_OS_MAC [[MAC]]
+// CHECK-DAG: #define TARGET_OS_OSX [[OSX]]
+// CHECK-DAG: #define TARGET_OS_IPHONE [[IPHONE]]
+// CHECK-DAG: #define TARGET_OS_IOS [[IOS]]
+// CHECK-DAG: #define TARGET_OS_TV [[TV]]
+// CHECK-DAG: #define TARGET_OS_WATCH [[WATCH]]
+// CHECK-DAG: #define TARGET_OS_DRIVERKIT [[DRIVERKIT]]
+// CHECK-DAG: #define TARGET_OS_MACCATALYST [[MACCATALYST]]
+// CHECK-DAG: #define TARGET_OS_SIMULATOR [[SIMULATOR]]
+// Deprecated
+// CHECK-DAG: #define TARGET_OS_EMBEDDED [[EMBEDDED]]
+// CHECK-DAG: #define TARGET_OS_NANO [[WATCH]]
+// CHECK-DAG: #define TARGET_IPHONE_SIMULATOR [[SIMULATOR]]
+// CHECK-DAG: #define TARGET_OS_UIKITFORMAC [[MACCATALYST]]
+// Non-darwin OSes
+// CHECK-DAG: #define TARGET_OS_WIN32 [[WINDOWS]]
+// CHECK-DAG: #define TARGET_OS_WINDOWS [[WINDOWS]]
+// CHECK-DAG: #define TARGET_OS_LINUX [[LINUX]]
+// CHECK-DAG: #define TARGET_OS_UNIX [[UNIX]]
clang/test/Driver/hip-offload-compress-zlib.hip
@@ -4,13 +4,13 @@
// Test compress bundled bitcode. // Test compress bundled bitcode.
-// RUN: rm -rf %T/a.bc+// RUN: rm -rf %t.bc
// RUN: %clang -c -v --target=x86_64-linux-gnu \ // RUN: %clang -c -v --target=x86_64-linux-gnu \
// RUN: -x hip --offload-arch=gfx1100 --offload-arch=gfx1101 \ // RUN: -x hip --offload-arch=gfx1100 --offload-arch=gfx1101 \
// RUN: -fgpu-rdc -nogpuinc -nogpulib \ // RUN: -fgpu-rdc -nogpuinc -nogpulib \
// RUN: %S/Inputs/hip_multiple_inputs/a.cu \ // RUN: %S/Inputs/hip_multiple_inputs/a.cu \
// RUN: --offload-compress --offload-device-only --gpu-bundle-output \ // RUN: --offload-compress --offload-device-only --gpu-bundle-output \
-// RUN: -o %T/a.bc \+// RUN: -o %t.bc \
// RUN: 2>&1 | FileCheck %s // RUN: 2>&1 | FileCheck %s
// CHECK: clang-offload-bundler{{.*}} -type=bc // CHECK: clang-offload-bundler{{.*}} -type=bc
@@ -23,7 +23,7 @@
// RUN: %clang --hip-link -### -v --target=x86_64-linux-gnu \ // RUN: %clang --hip-link -### -v --target=x86_64-linux-gnu \
// RUN: --offload-arch=gfx1100 --offload-arch=gfx1101 \ // RUN: --offload-arch=gfx1100 --offload-arch=gfx1101 \
// RUN: -fgpu-rdc -nogpulib \ // RUN: -fgpu-rdc -nogpulib \
-// RUN: %T/a.bc --offload-device-only \+// RUN: %t.bc --offload-device-only \
// RUN: 2>&1 | FileCheck -check-prefix=UNBUNDLE %s // RUN: 2>&1 | FileCheck -check-prefix=UNBUNDLE %s
// UNBUNDLE: clang-offload-bundler{{.*}} "-type=bc" // UNBUNDLE: clang-offload-bundler{{.*}} "-type=bc"
clang/test/Driver/hip-offload-compress-zstd.hip
@@ -4,13 +4,13 @@
// Test compress bundled bitcode. // Test compress bundled bitcode.
-// RUN: rm -rf %T/a.bc+// RUN: rm -rf %t.bc
// RUN: %clang -c -v --target=x86_64-linux-gnu \ // RUN: %clang -c -v --target=x86_64-linux-gnu \
// RUN: -x hip --offload-arch=gfx1100 --offload-arch=gfx1101 \ // RUN: -x hip --offload-arch=gfx1100 --offload-arch=gfx1101 \
// RUN: -fgpu-rdc -nogpuinc -nogpulib \ // RUN: -fgpu-rdc -nogpuinc -nogpulib \
// RUN: %S/Inputs/hip_multiple_inputs/a.cu \ // RUN: %S/Inputs/hip_multiple_inputs/a.cu \
// RUN: --offload-compress --offload-device-only --gpu-bundle-output \ // RUN: --offload-compress --offload-device-only --gpu-bundle-output \
-// RUN: -o %T/a.bc \+// RUN: -o %t.bc \
// RUN: 2>&1 | FileCheck %s // RUN: 2>&1 | FileCheck %s
// CHECK: clang-offload-bundler{{.*}} -type=bc // CHECK: clang-offload-bundler{{.*}} -type=bc
@@ -23,7 +23,7 @@
// RUN: %clang --hip-link -### -v --target=x86_64-linux-gnu \ // RUN: %clang --hip-link -### -v --target=x86_64-linux-gnu \
// RUN: --offload-arch=gfx1100 --offload-arch=gfx1101 \ // RUN: --offload-arch=gfx1100 --offload-arch=gfx1101 \
// RUN: -fgpu-rdc -nogpulib \ // RUN: -fgpu-rdc -nogpulib \
-// RUN: %T/a.bc --offload-device-only \+// RUN: %t.bc --offload-device-only \
// RUN: 2>&1 | FileCheck -check-prefix=UNBUNDLE %s // RUN: 2>&1 | FileCheck -check-prefix=UNBUNDLE %s
// UNBUNDLE: clang-offload-bundler{{.*}} "-type=bc" // UNBUNDLE: clang-offload-bundler{{.*}} "-type=bc"
clang/test/Driver/linker-wrapper-image.c
@@ -80,24 +80,33 @@
// CUDA-NEXT: br i1 icmp ne (ptr @__start_cuda_offloading_entries, ptr @__stop_cuda_offloading_entries), label %while.entry, label %while.end // CUDA-NEXT: br i1 icmp ne (ptr @__start_cuda_offloading_entries, ptr @__stop_cuda_offloading_entries), label %while.entry, label %while.end
// CUDA: while.entry: // CUDA: while.entry:
-// CUDA-NEXT: %entry1 = phi ptr [ @__start_cuda_offloading_entries, %entry ], [ %7, %if.end ]+// CUDA-NEXT: %entry1 = phi ptr [ @__start_cuda_offloading_entries, %entry ], [ %11, %if.end ]
-// CUDA-NEXT: %1 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 0+// CUDA-NEXT: %1 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 0
-// CUDA-NEXT: %addr = load ptr, ptr %1, align 8+// CUDA-NEXT: %addr = load ptr, ptr %1, align 8
-// CUDA-NEXT: %2 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 1+// CUDA-NEXT: %2 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 1
-// CUDA-NEXT: %name = load ptr, ptr %2, align 8+// CUDA-NEXT: %name = load ptr, ptr %2, align 8
-// CUDA-NEXT: %3 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 2+// CUDA-NEXT: %3 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 2
-// CUDA-NEXT: %size = load i64, ptr %3, align 4+// CUDA-NEXT: %size = load i64, ptr %3, align 4
-// CUDA-NEXT: %4 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 3+// CUDA-NEXT: %4 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 3
-// CUDA-NEXT: %flag = load i32, ptr %4, align 4+// CUDA-NEXT: %flags = load i32, ptr %4, align 4
-// CUDA-NEXT: %5 = icmp eq i64 %size, 0+// CUDA-NEXT: %5 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 4
-// CUDA-NEXT: br i1 %5, label %if.then, label %if.else+// CUDA-NEXT: %textype = load i32, ptr %5, align 4
+// CUDA-NEXT: %type = and i32 %flags, 7
+// CUDA-NEXT: %6 = and i32 %flags, 8
+// CUDA-NEXT: %extern = lshr i32 %6, 3
+// CUDA-NEXT: %7 = and i32 %flags, 16
+// CUDA-NEXT: %constant = lshr i32 %7, 4
+// CUDA-NEXT: %8 = and i32 %flags, 32
+// CUDA-NEXT: %normalized = lshr i32 %8, 5
+// CUDA-NEXT: %9 = icmp eq i64 %size, 0
+// CUDA-NEXT: br i1 %9, label %if.then, label %if.else
// CUDA: if.then: // CUDA: if.then:
-// CUDA-NEXT: %6 = call i32 @__cudaRegisterFunction(ptr %0, ptr %addr, ptr %name, ptr %name, i32 -1, ptr null, ptr null, ptr null, ptr null, ptr null)+// CUDA-NEXT: %10 = call i32 @__cudaRegisterFunction(ptr %0, ptr %addr, ptr %name, ptr %name, i32 -1, ptr null, ptr null, ptr null, ptr null, ptr null)
// CUDA-NEXT: br label %if.end // CUDA-NEXT: br label %if.end
// CUDA: if.else: // CUDA: if.else:
-// CUDA-NEXT: switch i32 %flag, label %if.end [+// CUDA-NEXT: switch i32 %type, label %if.end [
// CUDA-NEXT: i32 0, label %sw.global // CUDA-NEXT: i32 0, label %sw.global
// CUDA-NEXT: i32 1, label %sw.managed // CUDA-NEXT: i32 1, label %sw.managed
// CUDA-NEXT: i32 2, label %sw.surface // CUDA-NEXT: i32 2, label %sw.surface
@@ -105,22 +114,24 @@
// CUDA-NEXT: ] // CUDA-NEXT: ]
// CUDA: sw.global: // CUDA: sw.global:
-// CUDA-NEXT: call void @__cudaRegisterVar(ptr %0, ptr %addr, ptr %name, ptr %name, i32 0, i64 %size, i32 0, i32 0)+// CUDA-NEXT: call void @__cudaRegisterVar(ptr %0, ptr %addr, ptr %name, ptr %name, i32 %extern, i64 %size, i32 %constant, i32 0)
// CUDA-NEXT: br label %if.end // CUDA-NEXT: br label %if.end
// CUDA: sw.managed: // CUDA: sw.managed:
// CUDA-NEXT: br label %if.end // CUDA-NEXT: br label %if.end
// CUDA: sw.surface: // CUDA: sw.surface:
+// CUDA-NEXT: call void @__cudaRegisterSurface(ptr %0, ptr %addr, ptr %name, ptr %name, i32 %textype, i32 %extern)
// CUDA-NEXT: br label %if.end // CUDA-NEXT: br label %if.end
// CUDA: sw.texture: // CUDA: sw.texture:
+// CUDA-NEXT: call void @__cudaRegisterTexture(ptr %0, ptr %addr, ptr %name, ptr %name, i32 %textype, i32 %normalized, i32 %extern)
// CUDA-NEXT: br label %if.end // CUDA-NEXT: br label %if.end
// CUDA: if.end: // CUDA: if.end:
-// CUDA-NEXT: %7 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 1+// CUDA-NEXT: %11 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 1
-// CUDA-NEXT: %8 = icmp eq ptr %7, @__stop_cuda_offloading_entries+// CUDA-NEXT: %12 = icmp eq ptr %11, @__stop_cuda_offloading_entries
-// CUDA-NEXT: br i1 %8, label %while.end, label %while.entry+// CUDA-NEXT: br i1 %12, label %while.end, label %while.entry
// CUDA: while.end: // CUDA: while.end:
// CUDA-NEXT: ret void // CUDA-NEXT: ret void
@@ -168,7 +179,7 @@
// HIP-NEXT: br i1 icmp ne (ptr @__start_hip_offloading_entries, ptr @__stop_hip_offloading_entries), label %while.entry, label %while.end // HIP-NEXT: br i1 icmp ne (ptr @__start_hip_offloading_entries, ptr @__stop_hip_offloading_entries), label %while.entry, label %while.end
// HIP: while.entry: // HIP: while.entry:
-// HIP-NEXT: %entry1 = phi ptr [ @__start_hip_offloading_entries, %entry ], [ %7, %if.end ]+// HIP-NEXT: %entry1 = phi ptr [ @__start_hip_offloading_entries, %entry ], [ %11, %if.end ]
// HIP-NEXT: %1 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 0 // HIP-NEXT: %1 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 0
// HIP-NEXT: %addr = load ptr, ptr %1, align 8 // HIP-NEXT: %addr = load ptr, ptr %1, align 8
// HIP-NEXT: %2 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 1 // HIP-NEXT: %2 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 1
@@ -176,16 +187,25 @@
// HIP-NEXT: %3 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 2 // HIP-NEXT: %3 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 2
// HIP-NEXT: %size = load i64, ptr %3, align 4 // HIP-NEXT: %size = load i64, ptr %3, align 4
// HIP-NEXT: %4 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 3 // HIP-NEXT: %4 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 3
-// HIP-NEXT: %flag = load i32, ptr %4, align 4+// HIP-NEXT: %flags = load i32, ptr %4, align 4
-// HIP-NEXT: %5 = icmp eq i64 %size, 0+// HIP-NEXT: %5 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 0, i32 4
-// HIP-NEXT: br i1 %5, label %if.then, label %if.else+// HIP-NEXT: %textype = load i32, ptr %5, align 4
+// HIP-NEXT: %type = and i32 %flags, 7
+// HIP-NEXT: %6 = and i32 %flags, 8
+// HIP-NEXT: %extern = lshr i32 %6, 3
+// HIP-NEXT: %7 = and i32 %flags, 16
+// HIP-NEXT: %constant = lshr i32 %7, 4
+// HIP-NEXT: %8 = and i32 %flags, 32
+// HIP-NEXT: %normalized = lshr i32 %8, 5
+// HIP-NEXT: %9 = icmp eq i64 %size, 0
+// HIP-NEXT: br i1 %9, label %if.then, label %if.else
// HIP: if.then: // HIP: if.then:
-// HIP-NEXT: %6 = call i32 @__hipRegisterFunction(ptr %0, ptr %addr, ptr %name, ptr %name, i32 -1, ptr null, ptr null, ptr null, ptr null, ptr null)+// HIP-NEXT: %10 = call i32 @__hipRegisterFunction(ptr %0, ptr %addr, ptr %name, ptr %name, i32 -1, ptr null, ptr null, ptr null, ptr null, ptr null)
// HIP-NEXT: br label %if.end // HIP-NEXT: br label %if.end
// HIP: if.else: // HIP: if.else:
-// HIP-NEXT: switch i32 %flag, label %if.end [+// HIP-NEXT: switch i32 %type, label %if.end [
// HIP-NEXT: i32 0, label %sw.global // HIP-NEXT: i32 0, label %sw.global
// HIP-NEXT: i32 1, label %sw.managed // HIP-NEXT: i32 1, label %sw.managed
// HIP-NEXT: i32 2, label %sw.surface // HIP-NEXT: i32 2, label %sw.surface
@@ -193,22 +213,24 @@
// HIP-NEXT: ] // HIP-NEXT: ]
// HIP: sw.global: // HIP: sw.global:
-// HIP-NEXT: call void @__hipRegisterVar(ptr %0, ptr %addr, ptr %name, ptr %name, i32 0, i64 %size, i32 0, i32 0)+// HIP-NEXT: call void @__hipRegisterVar(ptr %0, ptr %addr, ptr %name, ptr %name, i32 %extern, i64 %size, i32 %constant, i32 0)
// HIP-NEXT: br label %if.end // HIP-NEXT: br label %if.end
// HIP: sw.managed: // HIP: sw.managed:
// HIP-NEXT: br label %if.end // HIP-NEXT: br label %if.end
// HIP: sw.surface: // HIP: sw.surface:
+// HIP-NEXT: call void @__hipRegisterSurface(ptr %0, ptr %addr, ptr %name, ptr %name, i32 %textype, i32 %extern)
// HIP-NEXT: br label %if.end // HIP-NEXT: br label %if.end
// HIP: sw.texture: // HIP: sw.texture:
+// HIP-NEXT: call void @__hipRegisterTexture(ptr %0, ptr %addr, ptr %name, ptr %name, i32 %textype, i32 %normalized, i32 %extern)
// HIP-NEXT: br label %if.end // HIP-NEXT: br label %if.end
// HIP: if.end: // HIP: if.end:
-// HIP-NEXT: %7 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 1+// HIP-NEXT: %11 = getelementptr inbounds %struct.__tgt_offload_entry, ptr %entry1, i64 1
-// HIP-NEXT: %8 = icmp eq ptr %7, @__stop_hip_offloading_entries+// HIP-NEXT: %12 = icmp eq ptr %11, @__stop_hip_offloading_entries
-// HIP-NEXT: br i1 %8, label %while.end, label %while.entry+// HIP-NEXT: br i1 %12, label %while.end, label %while.entry
// HIP: while.end: // HIP: while.end:
// HIP-NEXT: ret void // HIP-NEXT: ret void
clang/test/ExtractAPI/language.c
@@ -4,29 +4,42 @@
// RUN: %t/c.reference.output.json.in >> %t/c.reference.output.json // RUN: %t/c.reference.output.json.in >> %t/c.reference.output.json
// RUN: sed -e "s@INPUT_DIR@%{/t:regex_replacement}@g" \ // RUN: sed -e "s@INPUT_DIR@%{/t:regex_replacement}@g" \
// RUN: %t/objc.reference.output.json.in >> %t/objc.reference.output.json // RUN: %t/objc.reference.output.json.in >> %t/objc.reference.output.json
+// RUN: sed -e "s@INPUT_DIR@%{/t:regex_replacement}@g" \
+// RUN: %t/objcpp.reference.output.json.in >> %t/objcpp.reference.output.json
-// RUN: %clang -extract-api -x c-header -target arm64-apple-macosx \+// RUN: %clang_cc1 -extract-api -x c-header -triple arm64-apple-macosx \
// RUN: %t/c.h -o %t/c.output.json | FileCheck -allow-empty %s // RUN: %t/c.h -o %t/c.output.json | FileCheck -allow-empty %s
-// RUN: %clang -extract-api -x objective-c-header -target arm64-apple-macosx \+// RUN: %clang_cc1 -extract-api -x objective-c-header -triple arm64-apple-macosx \
// RUN: %t/objc.h -o %t/objc.output.json | FileCheck -allow-empty %s // RUN: %t/objc.h -o %t/objc.output.json | FileCheck -allow-empty %s
+// RUN: %clang_cc1 -extract-api -x objective-c++-header -triple arm64-apple-macosx \
+// RUN: %t/objcpp.h -o %t/objcpp.output.json | FileCheck -allow-empty %s
// Generator version is not consistent across test runs, normalize it. // Generator version is not consistent across test runs, normalize it.
// RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \ // RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \
// RUN: %t/c.output.json >> %t/c.output-normalized.json // RUN: %t/c.output.json >> %t/c.output-normalized.json
// RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \ // RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \
// RUN: %t/objc.output.json >> %t/objc.output-normalized.json // RUN: %t/objc.output.json >> %t/objc.output-normalized.json
+// RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \
+// RUN: %t/objcpp.output.json >> %t/objcpp.output-normalized.json
// RUN: diff %t/c.reference.output.json %t/c.output-normalized.json // RUN: diff %t/c.reference.output.json %t/c.output-normalized.json
// RUN: diff %t/objc.reference.output.json %t/objc.output-normalized.json // RUN: diff %t/objc.reference.output.json %t/objc.output-normalized.json
+// RUN: diff %t/objcpp.reference.output.json %t/objcpp.output-normalized.json
// CHECK-NOT: error: // CHECK-NOT: error:
// CHECK-NOT: warning: // CHECK-NOT: warning:
//--- c.h //--- c.h
char c; char c;
+///expected-no-diagnostics
//--- objc.h //--- objc.h
char objc; char objc;
+///expected-no-diagnostics
+
+//--- objcpp.h
+char objcpp;
+///expected-no-diagnostics
//--- c.reference.output.json.in //--- c.reference.output.json.in
{ {
@@ -196,3 +209,87 @@ char objc;
} }
] ]
} }
+//--- objcpp.reference.output.json.in
+{
+ "metadata": {
+ "formatVersion": {
+ "major": 0,
+ "minor": 5,
+ "patch": 3
+ },
+ "generator": "?"
+ },
+ "module": {
+ "name": "",
+ "platform": {
+ "architecture": "arm64",
+ "operatingSystem": {
+ "minimumVersion": {
+ "major": 11,
+ "minor": 0,
+ "patch": 0
+ },
+ "name": "macosx"
+ },
+ "vendor": "apple"
+ }
+ },
+ "relationships": [],
+ "symbols": [
+ {
+ "accessLevel": "public",
+ "declarationFragments": [
+ {
+ "kind": "typeIdentifier",
+ "preciseIdentifier": "c:C",
+ "spelling": "char"
+ },
+ {
+ "kind": "text",
+ "spelling": " "
+ },
+ {
+ "kind": "identifier",
+ "spelling": "objcpp"
+ },
+ {
+ "kind": "text",
+ "spelling": ";"
+ }
+ ],
+ "identifier": {
+ "interfaceLanguage": "objective-c++",
+ "precise": "c:@objcpp"
+ },
+ "kind": {
+ "displayName": "Global Variable",
+ "identifier": "objective-c++.var"
+ },
+ "location": {
+ "position": {
+ "character": 5,
+ "line": 0
+ },
+ "uri": "file://INPUT_DIR/objcpp.h"
+ },
+ "names": {
+ "navigator": [
+ {
+ "kind": "identifier",
+ "spelling": "objcpp"
+ }
+ ],
+ "subHeading": [
+ {
+ "kind": "identifier",
+ "spelling": "objcpp"
+ }
+ ],
+ "title": "objcpp"
+ },
+ "pathComponents": [
+ "objcpp"
+ ]
+ }
+ ]
+}
clang/test/Misc/target-invalid-cpu-note.c
@@ -1,7 +1,7 @@
// Use CHECK-NEXT instead of multiple CHECK-SAME to ensure we will fail if there is anything extra in the output. // Use CHECK-NEXT instead of multiple CHECK-SAME to ensure we will fail if there is anything extra in the output.
// RUN: not %clang_cc1 -triple armv5--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix ARM // RUN: not %clang_cc1 -triple armv5--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix ARM
// ARM: error: unknown target CPU 'not-a-cpu' // ARM: error: unknown target CPU 'not-a-cpu'
-// ARM-NEXT: note: valid target CPU values are: arm8, arm810, strongarm, strongarm110, strongarm1100, strongarm1110, arm7tdmi, arm7tdmi-s, arm710t, arm720t, arm9, arm9tdmi, arm920, arm920t, arm922t, arm940t, ep9312, arm10tdmi, arm1020t, arm9e, arm946e-s, arm966e-s, arm968e-s, arm10e, arm1020e, arm1022e, arm926ej-s, arm1136j-s, arm1136jf-s, mpcore, mpcorenovfp, arm1176jz-s, arm1176jzf-s, arm1156t2-s, arm1156t2f-s, cortex-m0, cortex-m0plus, cortex-m1, sc000, cortex-a5, cortex-a7, cortex-a8, cortex-a9, cortex-a12, cortex-a15, cortex-a17, krait, cortex-r4, cortex-r4f, cortex-r5, cortex-r7, cortex-r8, cortex-r52, sc300, cortex-m3, cortex-m4, cortex-m7, cortex-m23, cortex-m33, cortex-m35p, cortex-m55, cortex-m85, cortex-a32, cortex-a35, cortex-a53, cortex-a55, cortex-a57, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, cortex-a77, cortex-a78, cortex-a78c, cortex-a710, cortex-x1, cortex-x1c, neoverse-n1, neoverse-n2, neoverse-v1, cyclone, exynos-m3, exynos-m4, exynos-m5, kryo, iwmmxt, xscale, swift{{$}}+// ARM-NEXT: note: valid target CPU values are: arm8, arm810, strongarm, strongarm110, strongarm1100, strongarm1110, arm7tdmi, arm7tdmi-s, arm710t, arm720t, arm9, arm9tdmi, arm920, arm920t, arm922t, arm940t, ep9312, arm10tdmi, arm1020t, arm9e, arm946e-s, arm966e-s, arm968e-s, arm10e, arm1020e, arm1022e, arm926ej-s, arm1136j-s, arm1136jf-s, mpcore, mpcorenovfp, arm1176jz-s, arm1176jzf-s, arm1156t2-s, arm1156t2f-s, cortex-m0, cortex-m0plus, cortex-m1, sc000, cortex-a5, cortex-a7, cortex-a8, cortex-a9, cortex-a12, cortex-a15, cortex-a17, krait, cortex-r4, cortex-r4f, cortex-r5, cortex-r7, cortex-r8, cortex-r52, sc300, cortex-m3, cortex-m4, cortex-m7, cortex-m23, cortex-m33, cortex-m35p, cortex-m55, cortex-m85, cortex-m52, cortex-a32, cortex-a35, cortex-a53, cortex-a55, cortex-a57, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, cortex-a77, cortex-a78, cortex-a78c, cortex-a710, cortex-x1, cortex-x1c, neoverse-n1, neoverse-n2, neoverse-v1, cyclone, exynos-m3, exynos-m4, exynos-m5, kryo, iwmmxt, xscale, swift{{$}}
// RUN: not %clang_cc1 -triple arm64--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix AARCH64 // RUN: not %clang_cc1 -triple arm64--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix AARCH64
// AARCH64: error: unknown target CPU 'not-a-cpu' // AARCH64: error: unknown target CPU 'not-a-cpu'
clang/test/OpenMP/target_data_use_device_addr_codegen.cpp
@@ -144,7 +144,13 @@ int main() {
// CHECK: [[ARR_IDX6:%.+]] = getelementptr inbounds [4 x i32], ptr [[ARR_ADDR]], i64 0, i64 0 // CHECK: [[ARR_IDX6:%.+]] = getelementptr inbounds [4 x i32], ptr [[ARR_ADDR]], i64 0, i64 0
// CHECK: [[A_ADDR2:%.+]] = getelementptr inbounds %struct.S, ptr [[THIS]], i32 0, i32 0 // CHECK: [[A_ADDR2:%.+]] = getelementptr inbounds %struct.S, ptr [[THIS]], i32 0, i32 0
// CHECK: [[P4:%.+]] = mul nuw i64 [[CONV:%.+]], 4 // CHECK: [[P4:%.+]] = mul nuw i64 [[CONV:%.+]], 4
-// CHECK: [[ARR_END:%.+]] = getelementptr i32, ptr [[ARR_IDX6]], i32 1+// CHECK: [[A_ADDR3:%.+]] = getelementptr inbounds %struct.S, ptr [[THIS]], i32 0, i32 0
+// CHECK: [[L5:%.+]] = load i32, ptr [[A_ADDR3]]
+// CHECK: [[L6:%.+]] = sext i32 [[L5]] to i64
+// CHECK: [[LB_ADD_LEN:%lb_add_len]] = add nsw i64 -1, [[L6]]
+// CHECK: [[ARR_ADDR9:%.+]] = getelementptr inbounds %struct.S, ptr [[THIS]], i32 0, i32 3
+// CHECK: [[ARR_IDX10:%arrayidx.+]] = getelementptr inbounds [4 x i32], ptr [[ARR_ADDR9]], i64 0, i64 %lb_add_len
+// CHECK: [[ARR_END:%.+]] = getelementptr i32, ptr [[ARR_IDX10]], i32 1
// CHECK: [[E:%.+]] = ptrtoint ptr [[ARR_END]] to i64 // CHECK: [[E:%.+]] = ptrtoint ptr [[ARR_END]] to i64
// CHECK: [[B:%.+]] = ptrtoint ptr [[A_ADDR]] to i64 // CHECK: [[B:%.+]] = ptrtoint ptr [[A_ADDR]] to i64
// CHECK: [[DIFF:%.+]] = sub i64 [[E]], [[B]] // CHECK: [[DIFF:%.+]] = sub i64 [[E]], [[B]]
clang/test/ParserOpenACC/parse-constructs.c
@@ -7,6 +7,17 @@ void func() {
#pragma acc #pragma acc
for(;;){} for(;;){}
+ // expected-error@+4{{expected OpenACC directive}}
+ // expected-error@+3{{expected clause-list or newline in OpenACC directive}}
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc(whatever) routine
+
+ // expected-error@+3{{expected OpenACC directive}}
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+#pragma acc) routine
+
// expected-error@+2{{invalid OpenACC directive 'invalid'}} // expected-error@+2{{invalid OpenACC directive 'invalid'}}
// expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
#pragma acc invalid #pragma acc invalid
clang/test/ParserOpenACC/parse-wait-construct.c
@@ -0,0 +1,157 @@
+// RUN: %clang_cc1 %s -verify -fopenacc
+
+void func() {
+ int i, j;
+
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait
+
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait clause-list
+
+ // expected-error@+3{{expected ')'}}
+ // expected-note@+2{{to match this '('}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (
+
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait ()
+
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait () clause-list
+
+ // expected-error@+4{{expected expression}}
+ // expected-error@+3{{expected ')'}}
+ // expected-note@+2{{to match this '('}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (devnum:
+
+ // expected-error@+2{{expected expression}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (devnum:)
+
+ // expected-error@+3{{expected expression}}
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (devnum:) clause-list
+
+ // expected-error@+4{{expected ':'}}
+ // expected-error@+3{{expected ')'}}
+ // expected-note@+2{{to match this '('}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (devnum: i + j
+
+ // expected-error@+2{{expected ':'}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (devnum: i + j)
+
+ // expected-error@+3{{expected ':'}}
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (devnum: i + j) clause-list
+
+ // expected-error@+3{{expected ')'}}
+ // expected-note@+2{{to match this '('}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (queues:
+
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (queues:)
+
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (queues:) clause-list
+
+ // expected-error@+3{{expected ')'}}
+ // expected-note@+2{{to match this '('}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (devnum: i + j:queues:
+
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (devnum: i + j:queues:)
+
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (devnum: i + j:queues:) clause-list
+
+ // expected-error@+4{{use of undeclared identifier 'devnum'}}
+ // expected-error@+3{{expected ')'}}
+ // expected-note@+2{{to match this '('}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (queues:devnum: i + j
+
+ // expected-error@+2{{use of undeclared identifier 'devnum'}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (queues:devnum: i + j)
+
+ // expected-error@+3{{use of undeclared identifier 'devnum'}}
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait (queues:devnum: i + j) clause-list
+
+ // expected-error@+3{{expected ')'}}
+ // expected-note@+2{{to match this '('}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(i, j, 1+1, 3.3
+
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(i, j, 1+1, 3.3)
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(i, j, 1+1, 3.3) clause-list
+
+ // expected-error@+4{{expected expression}}
+ // expected-error@+3{{expected ')'}}
+ // expected-note@+2{{to match this '('}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(,
+
+ // expected-error@+2{{expected expression}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(,)
+
+ // expected-error@+3{{expected expression}}
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(,) clause-list
+
+ // expected-error@+3{{expected ')'}}
+ // expected-note@+2{{to match this '('}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(queues:i, j, 1+1, 3.3
+
+ // expected-error@+4{{expected expression}}
+ // expected-error@+3{{expected ')'}}
+ // expected-note@+2{{to match this '('}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(queues:i, j, 1+1, 3.3,
+
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(queues:i, j, 1+1, 3.3)
+
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(queues:i, j, 1+1, 3.3) clause-list
+
+ // expected-error@+3{{expected ')'}}
+ // expected-note@+2{{to match this '('}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(devnum:3:i, j, 1+1, 3.3
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(devnum:3:i, j, 1+1, 3.3)
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(devnum:3:i, j, 1+1, 3.3) clause-list
+
+ // expected-error@+3{{expected ')'}}
+ // expected-note@+2{{to match this '('}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(devnum:3:queues:i, j, 1+1, 3.3
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(devnum:3:queues:i, j, 1+1, 3.3)
+ // expected-warning@+2{{OpenACC clause parsing not yet implemented}}
+ // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}}
+ #pragma acc wait(devnum:3:queues:i, j, 1+1, 3.3) clause-list
+}
clang/test/Preprocessor/init-aarch64.c
@@ -217,6 +217,11 @@
// AARCH64-NEXT: #define __LONG_MAX__ 9223372036854775807L // AARCH64-NEXT: #define __LONG_MAX__ 9223372036854775807L
// AARCH64-NEXT: #define __LONG_WIDTH__ 64 // AARCH64-NEXT: #define __LONG_WIDTH__ 64
// AARCH64-NEXT: #define __LP64__ 1 // AARCH64-NEXT: #define __LP64__ 1
+// AARCH64-NEXT: #define __MEMORY_SCOPE_DEVICE 1
+// AARCH64-NEXT: #define __MEMORY_SCOPE_SINGLE 4
+// AARCH64-NEXT: #define __MEMORY_SCOPE_SYSTEM 0
+// AARCH64-NEXT: #define __MEMORY_SCOPE_WRKGRP 2
+// AARCH64-NEXT: #define __MEMORY_SCOPE_WVFRNT 3
// AARCH64-NEXT: #define __NO_INLINE__ 1 // AARCH64-NEXT: #define __NO_INLINE__ 1
// AARCH64-NEXT: #define __NO_MATH_ERRNO__ 1 // AARCH64-NEXT: #define __NO_MATH_ERRNO__ 1
// AARCH64-NEXT: #define __OBJC_BOOL_IS_BOOL 0 // AARCH64-NEXT: #define __OBJC_BOOL_IS_BOOL 0
clang/test/Preprocessor/init-loongarch.c
@@ -177,6 +177,11 @@
// LA32: #define __LONG_LONG_MAX__ 9223372036854775807LL // LA32: #define __LONG_LONG_MAX__ 9223372036854775807LL
// LA32: #define __LONG_MAX__ 2147483647L // LA32: #define __LONG_MAX__ 2147483647L
// LA32: #define __LONG_WIDTH__ 32 // LA32: #define __LONG_WIDTH__ 32
+// LA32: #define __MEMORY_SCOPE_DEVICE 1
+// LA32: #define __MEMORY_SCOPE_SINGLE 4
+// LA32: #define __MEMORY_SCOPE_SYSTEM 0
+// LA32: #define __MEMORY_SCOPE_WRKGRP 2
+// LA32: #define __MEMORY_SCOPE_WVFRNT 3
// LA32: #define __NO_INLINE__ 1 // LA32: #define __NO_INLINE__ 1
// LA32: #define __NO_MATH_ERRNO__ 1 // LA32: #define __NO_MATH_ERRNO__ 1
// LA32: #define __OBJC_BOOL_IS_BOOL 0 // LA32: #define __OBJC_BOOL_IS_BOOL 0
@@ -494,6 +499,11 @@
// LA64: #define __LONG_MAX__ 9223372036854775807L // LA64: #define __LONG_MAX__ 9223372036854775807L
// LA64: #define __LONG_WIDTH__ 64 // LA64: #define __LONG_WIDTH__ 64
// LA64: #define __LP64__ 1 // LA64: #define __LP64__ 1
+// LA64: #define __MEMORY_SCOPE_DEVICE 1
+// LA64: #define __MEMORY_SCOPE_SINGLE 4
+// LA64: #define __MEMORY_SCOPE_SYSTEM 0
+// LA64: #define __MEMORY_SCOPE_WRKGRP 2
+// LA64: #define __MEMORY_SCOPE_WVFRNT 3
// LA64: #define __NO_INLINE__ 1 // LA64: #define __NO_INLINE__ 1
// LA64: #define __NO_MATH_ERRNO__ 1 // LA64: #define __NO_MATH_ERRNO__ 1
// LA64: #define __OBJC_BOOL_IS_BOOL 0 // LA64: #define __OBJC_BOOL_IS_BOOL 0
clang/test/Preprocessor/init.c
@@ -1742,6 +1742,11 @@
// WEBASSEMBLY64-NEXT:#define __LONG_MAX__ 9223372036854775807L // WEBASSEMBLY64-NEXT:#define __LONG_MAX__ 9223372036854775807L
// WEBASSEMBLY64-NEXT:#define __LONG_WIDTH__ 64 // WEBASSEMBLY64-NEXT:#define __LONG_WIDTH__ 64
// WEBASSEMBLY64-NEXT:#define __LP64__ 1 // WEBASSEMBLY64-NEXT:#define __LP64__ 1
+// WEBASSEMBLY-NEXT:#define __MEMORY_SCOPE_DEVICE 1
+// WEBASSEMBLY-NEXT:#define __MEMORY_SCOPE_SINGLE 4
+// WEBASSEMBLY-NEXT:#define __MEMORY_SCOPE_SYSTEM 0
+// WEBASSEMBLY-NEXT:#define __MEMORY_SCOPE_WRKGRP 2
+// WEBASSEMBLY-NEXT:#define __MEMORY_SCOPE_WVFRNT 3
// WEBASSEMBLY-NEXT:#define __NO_INLINE__ 1 // WEBASSEMBLY-NEXT:#define __NO_INLINE__ 1
// WEBASSEMBLY-NEXT:#define __NO_MATH_ERRNO__ 1 // WEBASSEMBLY-NEXT:#define __NO_MATH_ERRNO__ 1
// WEBASSEMBLY-NEXT:#define __OBJC_BOOL_IS_BOOL 0 // WEBASSEMBLY-NEXT:#define __OBJC_BOOL_IS_BOOL 0
@@ -2057,6 +2062,11 @@
// AVR:#define __LDBL_MIN__ 1.17549435e-38L // AVR:#define __LDBL_MIN__ 1.17549435e-38L
// AVR:#define __LONG_LONG_MAX__ 9223372036854775807LL // AVR:#define __LONG_LONG_MAX__ 9223372036854775807LL
// AVR:#define __LONG_MAX__ 2147483647L // AVR:#define __LONG_MAX__ 2147483647L
+// AVR:#define __MEMORY_SCOPE_DEVICE 1
+// AVR:#define __MEMORY_SCOPE_SINGLE 4
+// AVR:#define __MEMORY_SCOPE_SYSTEM 0
+// AVR:#define __MEMORY_SCOPE_WRKGRP 2
+// AVR:#define __MEMORY_SCOPE_WVFRNT 3
// AVR:#define __NO_INLINE__ 1 // AVR:#define __NO_INLINE__ 1
// AVR:#define __ORDER_BIG_ENDIAN__ 4321 // AVR:#define __ORDER_BIG_ENDIAN__ 4321
// AVR:#define __ORDER_LITTLE_ENDIAN__ 1234 // AVR:#define __ORDER_LITTLE_ENDIAN__ 1234
@@ -2348,6 +2358,11 @@
// RISCV32: #define __LITTLE_ENDIAN__ 1 // RISCV32: #define __LITTLE_ENDIAN__ 1
// RISCV32: #define __LONG_LONG_MAX__ 9223372036854775807LL // RISCV32: #define __LONG_LONG_MAX__ 9223372036854775807LL
// RISCV32: #define __LONG_MAX__ 2147483647L // RISCV32: #define __LONG_MAX__ 2147483647L
+// RISCV32: #define __MEMORY_SCOPE_DEVICE 1
+// RISCV32: #define __MEMORY_SCOPE_SINGLE 4
+// RISCV32: #define __MEMORY_SCOPE_SYSTEM 0
+// RISCV32: #define __MEMORY_SCOPE_WRKGRP 2
+// RISCV32: #define __MEMORY_SCOPE_WVFRNT 3
// RISCV32: #define __NO_INLINE__ 1 // RISCV32: #define __NO_INLINE__ 1
// RISCV32: #define __POINTER_WIDTH__ 32 // RISCV32: #define __POINTER_WIDTH__ 32
// RISCV32: #define __PRAGMA_REDEFINE_EXTNAME 1 // RISCV32: #define __PRAGMA_REDEFINE_EXTNAME 1
@@ -2555,6 +2570,11 @@
// RISCV64: #define __LONG_LONG_MAX__ 9223372036854775807LL // RISCV64: #define __LONG_LONG_MAX__ 9223372036854775807LL
// RISCV64: #define __LONG_MAX__ 9223372036854775807L // RISCV64: #define __LONG_MAX__ 9223372036854775807L
// RISCV64: #define __LP64__ 1 // RISCV64: #define __LP64__ 1
+// RISCV64: #define __MEMORY_SCOPE_DEVICE 1
+// RISCV64: #define __MEMORY_SCOPE_SINGLE 4
+// RISCV64: #define __MEMORY_SCOPE_SYSTEM 0
+// RISCV64: #define __MEMORY_SCOPE_WRKGRP 2
+// RISCV64: #define __MEMORY_SCOPE_WVFRNT 3
// RISCV64: #define __NO_INLINE__ 1 // RISCV64: #define __NO_INLINE__ 1
// RISCV64: #define __POINTER_WIDTH__ 64 // RISCV64: #define __POINTER_WIDTH__ 64
// RISCV64: #define __PRAGMA_REDEFINE_EXTNAME 1 // RISCV64: #define __PRAGMA_REDEFINE_EXTNAME 1
clang/test/Sema/aarch64-sve2p1-intrinsics/acle_sve2p1_imm.cpp
@@ -167,3 +167,21 @@ void test_svpmov_lane(){
zn_u32 = svpmov_lane_u32_m(zn_u32, pn, 5); // expected-error {{argument value 5 is outside the valid range [1, 3]}} zn_u32 = svpmov_lane_u32_m(zn_u32, pn, 5); // expected-error {{argument value 5 is outside the valid range [1, 3]}}
zn_u64 = svpmov_lane_u64_m(zn_u64, pn, 8); // expected-error {{argument value 8 is outside the valid range [1, 7]}} zn_u64 = svpmov_lane_u64_m(zn_u64, pn, 8); // expected-error {{argument value 8 is outside the valid range [1, 7]}}
} }
+
+__attribute__((target("+sve2p1")))
+void test_svget_svset_b(uint64_t idx, svboolx2_t tuple2, svboolx4_t tuple4, svbool_t res){
+ svset2(tuple2, -1, res); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 1]}}
+ svset2(tuple2, 2, res); // expected-error {{argument value 2 is outside the valid range [0, 1]}}
+ svset4(tuple4, -1, res); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 3]}}
+ svset4(tuple4, 4, res); // expected-error {{argument value 4 is outside the valid range [0, 3]}}
+
+ svget2(tuple2, -1); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 1]}}
+ svget2(tuple2, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}}
+ svget4(tuple4, -1); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 3]}}
+ svget4(tuple4, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}}
+
+ svset2(tuple2, idx, res); // expected-error {{argument to 'svste2' must be a constant integer}}
+ svset4(tupl4, idx, res); // expected-error {{argument to 'svset4' must be a constant integer}}
+ svget2(tuple2, idx); // expected-error {{argument to 'svget2' must be a constant integer}}
+ svget4(tuple4, idx); // expected-error {{argument to 'svget4' must be a constant integer}}
+}
clang/test/Sema/builtin-expect-with-probability.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s // RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -fexperimental-new-constant-interpreter %s
__attribute__((noreturn)) extern void bar(); __attribute__((noreturn)) extern void bar();
clang/test/Sema/scoped-atomic-ops.c
@@ -0,0 +1,101 @@
+// RUN: %clang_cc1 -x c -triple=amdgcn-amd-amdhsa -verify -fsyntax-only %s
+// RUN: %clang_cc1 -x c -triple=x86_64-pc-linux-gnu -verify -fsyntax-only %s
+
+int fi1a(int *i) {
+ int v;
+ __scoped_atomic_load(i, &v, __ATOMIC_RELAXED); // expected-error {{too few arguments to function call, expected 4, have 3}}
+ __scoped_atomic_load(i, &v, __ATOMIC_RELAXED, 42); // expected-error {{synchronization scope argument to atomic operation is invalid}}
+ __scoped_atomic_load(i, &v, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+ return v;
+}
+
+int fi1b(int *i) {
+ *i = __scoped_atomic_load_n(i, __ATOMIC_RELAXED); // expected-error {{too few arguments to function call, expected 3, have 2}}
+ *i = __scoped_atomic_load_n(i, __ATOMIC_RELAXED, 42); // expected-error {{synchronization scope argument to atomic operation is invalid}}
+ *i = __scoped_atomic_load_n(i, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+ return *i;
+}
+
+int fi2a(int *i) {
+ int v;
+ __scoped_atomic_store(i, &v, __ATOMIC_RELAXED); // expected-error {{too few arguments to function call, expected 4, have 3}}
+ __scoped_atomic_store(i, &v, __ATOMIC_RELAXED, 42); // expected-error {{synchronization scope argument to atomic operation is invalid}}
+ __scoped_atomic_store(i, &v, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+ return v;
+}
+
+void fi2b(int *i) {
+ __scoped_atomic_store_n(i, 1, __ATOMIC_RELAXED); // expected-error {{too few arguments to function call, expected 4, have 3}}
+ __scoped_atomic_store_n(i, 1, __ATOMIC_RELAXED, 42); // expected-error {{synchronization scope argument to atomic operation is invalid}}
+ __scoped_atomic_store_n(i, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+}
+
+void fi3a(int *a, int *b, int *c, int *d, int *e, int *f, int *g, int *h) {
+ *a = __scoped_atomic_fetch_add(a, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+ *b = __scoped_atomic_fetch_sub(b, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+ *c = __scoped_atomic_fetch_and(c, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+ *d = __scoped_atomic_fetch_or(d, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+ *e = __scoped_atomic_fetch_xor(e, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+ *f = __scoped_atomic_fetch_nand(f, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+ *g = __scoped_atomic_fetch_min(g, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+ *h = __scoped_atomic_fetch_max(h, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+}
+
+void fi3b(int *a, int *b, int *c, int *d, int *e, int *f, int *g, int *h) {
+ *a = __scoped_atomic_fetch_add(1, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM); // expected-error {{address argument to atomic builtin must be a pointer ('int' invalid)}}
+ *b = __scoped_atomic_fetch_sub(1, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM); // expected-error {{address argument to atomic builtin must be a pointer ('int' invalid)}}
+ *c = __scoped_atomic_fetch_and(1, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM); // expected-error {{address argument to atomic builtin must be a pointer ('int' invalid)}}
+ *d = __scoped_atomic_fetch_or(1, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM); // expected-error {{address argument to atomic builtin must be a pointer ('int' invalid)}}
+ *e = __scoped_atomic_fetch_xor(1, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM); // expected-error {{address argument to atomic builtin must be a pointer ('int' invalid)}}
+ *f = __scoped_atomic_fetch_nand(1, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM); // expected-error {{address argument to atomic builtin must be a pointer ('int' invalid)}}
+ *g = __scoped_atomic_fetch_min(1, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM); // expected-error {{address argument to atomic builtin must be a pointer ('int' invalid)}}
+ *h = __scoped_atomic_fetch_max(1, 1, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM); // expected-error {{address argument to atomic builtin must be a pointer ('int' invalid)}}
+}
+
+void fi3c(int *a, int *b, int *c, int *d, int *e, int *f, int *g, int *h) {
+ *a = __scoped_atomic_fetch_add(a, 1, __ATOMIC_RELAXED); // expected-error {{too few arguments to function call, expected 4, have 3}}
+ *b = __scoped_atomic_fetch_sub(b, 1, __ATOMIC_RELAXED); // expected-error {{too few arguments to function call, expected 4, have 3}}
+ *c = __scoped_atomic_fetch_and(c, 1, __ATOMIC_RELAXED); // expected-error {{too few arguments to function call, expected 4, have 3}}
+ *d = __scoped_atomic_fetch_or(d, 1, __ATOMIC_RELAXED); // expected-error {{too few arguments to function call, expected 4, have 3}}
+ *e = __scoped_atomic_fetch_xor(e, 1, __ATOMIC_RELAXED); // expected-error {{too few arguments to function call, expected 4, have 3}}
+ *f = __scoped_atomic_fetch_nand(f, 1, __ATOMIC_RELAXED); // expected-error {{too few arguments to function call, expected 4, have 3}}
+ *g = __scoped_atomic_fetch_min(g, 1, __ATOMIC_RELAXED); // expected-error {{too few arguments to function call, expected 4, have 3}}
+ *h = __scoped_atomic_fetch_max(h, 1, __ATOMIC_RELAXED); // expected-error {{too few arguments to function call, expected 4, have 3}}
+}
+
+void fi3d(int *a, int *b, int *c, int *d, int *e, int *f, int *g, int *h) {
+ *a = __scoped_atomic_fetch_add(a, 1, __ATOMIC_RELAXED, 42); // expected-error {{synchronization scope argument to atomic operation is invalid}}
+ *b = __scoped_atomic_fetch_sub(b, 1, __ATOMIC_RELAXED, 42); // expected-error {{synchronization scope argument to atomic operation is invalid}}
+ *c = __scoped_atomic_fetch_and(c, 1, __ATOMIC_RELAXED, 42); // expected-error {{synchronization scope argument to atomic operation is invalid}}
+ *d = __scoped_atomic_fetch_or(d, 1, __ATOMIC_RELAXED, 42); // expected-error {{synchronization scope argument to atomic operation is invalid}}
+ *e = __scoped_atomic_fetch_xor(e, 1, __ATOMIC_RELAXED, 42); // expected-error {{synchronization scope argument to atomic operation is invalid}}
+ *f = __scoped_atomic_fetch_nand(f, 1, __ATOMIC_RELAXED, 42); // expected-error {{synchronization scope argument to atomic operation is invalid}}
+ *g = __scoped_atomic_fetch_min(g, 1, __ATOMIC_RELAXED, 42); // expected-error {{synchronization scope argument to atomic operation is invalid}}
+ *h = __scoped_atomic_fetch_max(h, 1, __ATOMIC_RELAXED, 42); // expected-error {{synchronization scope argument to atomic operation is invalid}}
+}
+
+int fi4a(int *i) {
+ int cmp = 0;
+ int desired = 1;
+ return __scoped_atomic_compare_exchange(i, &cmp, &desired, 0,
+ __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE,
+ __MEMORY_SCOPE_SYSTEM);
+}
+
+int fi5a(int *i) {
+ int cmp = 0;
+ return __scoped_atomic_compare_exchange_n(i, &cmp, 1, 1, __ATOMIC_ACQUIRE,
+ __ATOMIC_ACQUIRE,
+ __MEMORY_SCOPE_SYSTEM);
+}
+
+int fi6a(int *c, int *d) {
+ int ret;
+ __scoped_atomic_exchange(c, d, &ret, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
+ return ret;
+}
+
+int fi7a(_Bool *c) {
+ return __scoped_atomic_exchange_n(c, 1, __ATOMIC_RELAXED,
+ __MEMORY_SCOPE_SYSTEM);
+}
clang/test/Sema/switch-default.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wswitch-default %s
+
+int f1(int a) {
+ switch (a) { // expected-warning {{'switch' missing 'default' label}}
+ case 1: a++; break;
+ case 2: a += 2; break;
+ }
+ return a;
+}
+
+int f2(int a) {
+ switch (a) { // no-warning
+ default:
+ ;
+ }
+ return a;
+}
clang/test/SemaCXX/coro-lifetimebound.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only -verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only -verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused -Wno-c++23-lambda-attributes
#include "Inputs/std-coroutine.h" #include "Inputs/std-coroutine.h"
@@ -64,14 +64,8 @@ Co<int> bar_coro(const int &b, int c) {
: bar_coro(0, 1); // expected-warning {{returning address of local temporary object}} : bar_coro(0, 1); // expected-warning {{returning address of local temporary object}}
} }
-#define CORO_WRAPPER \
- _Pragma("clang diagnostic push") \
- _Pragma("clang diagnostic ignored \"-Wc++23-extensions\"") \
- [[clang::coro_wrapper]] \
- _Pragma("clang diagnostic pop")
-
void lambdas() { void lambdas() {
- auto unsafe_lambda = [] CORO_WRAPPER (int b) {+ auto unsafe_lambda = [] [[clang::coro_wrapper]] (int b) {
return foo_coro(b); // expected-warning {{address of stack memory associated with parameter}} return foo_coro(b); // expected-warning {{address of stack memory associated with parameter}}
}; };
auto coro_lambda = [] (const int&) -> Co<int> { auto coro_lambda = [] (const int&) -> Co<int> {
clang/test/SemaCXX/coro-return-type-and-wrapper.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only -verify -Wall -Wextra+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only -verify -Wall -Wextra -Wno-c++23-lambda-attributes
#include "Inputs/std-coroutine.h" #include "Inputs/std-coroutine.h"
using std::suspend_always; using std::suspend_always;
@@ -45,11 +45,6 @@ Co<int> non_marked_wrapper(int b) { return foo_coro(b); }
} // namespace using_decl } // namespace using_decl
namespace lambdas { namespace lambdas {
-#define CORO_WRAPPER \
- _Pragma("clang diagnostic push") \
- _Pragma("clang diagnostic ignored \"-Wc++23-extensions\"") \
- [[clang::coro_wrapper]] \
- _Pragma("clang diagnostic pop")
void foo() { void foo() {
auto coro_lambda = []() -> Gen<int> { auto coro_lambda = []() -> Gen<int> {
@@ -59,7 +54,7 @@ void foo() {
auto not_allowed_wrapper = []() -> Gen<int> { auto not_allowed_wrapper = []() -> Gen<int> {
return foo_coro(1); return foo_coro(1);
}; };
- auto allowed_wrapper = [] CORO_WRAPPER() -> Gen<int> {+ auto allowed_wrapper = [] [[clang::coro_wrapper]] () -> Gen<int> {
return foo_coro(1); return foo_coro(1);
}; };
} }
clang/test/SemaCXX/cxx1z-copy-omission.cpp
@@ -171,3 +171,30 @@ namespace CtorTemplateBeatsNonTemplateConversionFn {
Foo f(Derived d) { return d; } // expected-error {{invokes a deleted function}} Foo f(Derived d) { return d; } // expected-error {{invokes a deleted function}}
Foo g(Derived d) { return Foo(d); } // ok, calls constructor Foo g(Derived d) { return Foo(d); } // ok, calls constructor
} }
+
+// Make sure we don't consider conversion functions for guaranteed copy elision
+namespace GH39319 {
+struct A {
+ A();
+ A(const A&) = delete; // expected-note {{'A' has been explicitly marked deleted here}}
+};
+struct B {
+ operator A();
+} C;
+A::A() : A(C) {} // expected-error {{call to deleted constructor of}}
+
+struct A2 {
+ struct B2 {
+ operator A2();
+ };
+ A2() : A2(B2()) {} // expected-error {{call to deleted constructor of}}
+ A2(const A2&) = delete; // expected-note {{'A2' has been explicitly marked deleted here}}
+};
+
+template<typename A3>
+class B3 : A3 {
+ template<bool = C3<B3>()> // expected-warning 2{{use of function template name with no prior declaration in function call with explicit}}
+ B3();
+}; B3(); // expected-error {{deduction guide declaration without trailing return type}} \
+ // expected-note {{while building implicit deduction guide first needed here}}
+}
clang/test/SemaCXX/warn-thread-safety-analysis.cpp
@@ -1702,6 +1702,8 @@ struct TestScopedLockable {
bool getBool(); bool getBool();
+ bool lock2Bool(MutexLock);
+
void foo1() { void foo1() {
MutexLock mulock(&mu1); MutexLock mulock(&mu1);
a = 5; a = 5;
@@ -1718,6 +1720,12 @@ struct TestScopedLockable {
MutexLock{&mu1}, a = 5; MutexLock{&mu1}, a = 5;
} }
+ void temporary_cfg(int x) {
+ // test the case where a pair of temporary Ctor and Dtor is in different CFG blocks
+ lock2Bool(MutexLock{&mu1}) || x;
+ MutexLock{&mu1}; // no-warn
+ }
+
void lifetime_extension() { void lifetime_extension() {
const MutexLock &mulock = MutexLock(&mu1); const MutexLock &mulock = MutexLock(&mu1);
a = 5; a = 5;
clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl
@@ -5,6 +5,14 @@ typedef vector<float, 3> float3;
RWBuffer<float3> Buffer; RWBuffer<float3> Buffer;
+// expected-error@+2 {{class template 'RWBuffer' requires template arguments}}
+// expected-note@*:* {{template declaration from hidden source: template <class element_type> class RWBuffer final}}
+RWBuffer BufferErr1;
+
+// expected-error@+2 {{too few template arguments for class template 'RWBuffer'}}
+// expected-note@*:* {{template declaration from hidden source: template <class element_type> class RWBuffer final}}
+RWBuffer<> BufferErr2;
+
[numthreads(1,1,1)] [numthreads(1,1,1)]
void main() { void main() {
(void)Buffer.h; // expected-error {{'h' is a private member of 'hlsl::RWBuffer<float __attribute__((ext_vector_type(3)))>'}} (void)Buffer.h; // expected-error {{'h' is a private member of 'hlsl::RWBuffer<float __attribute__((ext_vector_type(3)))>'}}
clang/test/SemaTemplate/GH71595.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++20 -verify %s
[diff truncated]