139 changes: 139 additions & 0 deletions clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr-c23.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
// RUN: %check_clang_tidy %s modernize-use-nullptr %t -- -- -std=c23

#define NULL 0

void test_assignment() {
int *p1 = 0;
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr [modernize-use-nullptr]
// CHECK-FIXES: int *p1 = nullptr;
p1 = 0;
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use nullptr
// CHECK-FIXES: p1 = nullptr;

int *p2 = NULL;
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr
// CHECK-FIXES: int *p2 = nullptr;

p2 = p1;
// CHECK-FIXES: p2 = p1;

const int null = 0;
int *p3 = &null;

p3 = NULL;
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use nullptr
// CHECK-FIXES: p3 = nullptr;

int *p4 = p3;

int i1 = 0;

int i2 = NULL;

int i3 = null;

int *p5, *p6, *p7;
p5 = p6 = p7 = NULL;
// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use nullptr
// CHECK-FIXES: p5 = p6 = p7 = nullptr;
}

void test_function(int *p) {}

void test_function_no_ptr_param(int i) {}

void test_function_call() {
test_function(0);
// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use nullptr
// CHECK-FIXES: test_function(nullptr);

test_function(NULL);
// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use nullptr
// CHECK-FIXES: test_function(nullptr);

test_function_no_ptr_param(0);
}

char *test_function_return1() {
return 0;
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr
// CHECK-FIXES: return nullptr;
}

void *test_function_return2() {
return NULL;
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr
// CHECK-FIXES: return nullptr;
}

int test_function_return4() {
return 0;
}

int test_function_return5() {
return NULL;
}

int *test_function_return_cast1() {
return(int)0;
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr
// CHECK-FIXES: return nullptr;
}

int *test_function_return_cast2() {
#define RET return
RET(int)0;
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use nullptr
// CHECK-FIXES: RET nullptr;
#undef RET
}

// Test parentheses expressions resulting in a nullptr.
int *test_parentheses_expression1() {
return(0);
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr
// CHECK-FIXES: return(nullptr);
}

int *test_parentheses_expression2() {
return((int)(0.0f));
// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr
// CHECK-FIXES: return(nullptr);
}

int *test_nested_parentheses_expression() {
return((((0))));
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr
// CHECK-FIXES: return((((nullptr))));
}

void test_const_pointers() {
const int *const_p1 = 0;
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use nullptr
// CHECK-FIXES: const int *const_p1 = nullptr;
const int *const_p2 = NULL;
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use nullptr
// CHECK-FIXES: const int *const_p2 = nullptr;
const int *const_p3 = (int)0;
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use nullptr
// CHECK-FIXES: const int *const_p3 = nullptr;
const int *const_p4 = (int)0.0f;
// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use nullptr
// CHECK-FIXES: const int *const_p4 = nullptr;
}

void test_nested_implicit_cast_expr() {
int func0(void*, void*);
int func1(int, void*, void*);

(double)func1(0, 0, 0);
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use nullptr
// CHECK-MESSAGES: :[[@LINE-2]]:23: warning: use nullptr
// CHECK-FIXES: (double)func1(0, nullptr, nullptr);
(double)func1(func0(0, 0), 0, 0);
// CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use nullptr
// CHECK-MESSAGES: :[[@LINE-2]]:26: warning: use nullptr
// CHECK-MESSAGES: :[[@LINE-3]]:30: warning: use nullptr
// CHECK-MESSAGES: :[[@LINE-4]]:33: warning: use nullptr
// CHECK-FIXES: (double)func1(func0(nullptr, nullptr), nullptr, nullptr);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: clang-tidy %s -checks=-*,modernize-use-nullptr -- | count 0
// RUN: clang-tidy %s -checks=-*,modernize-use-nullptr -- -std=c17 | count 0

// Note: this test expects no diagnostics, but FileCheck cannot handle that,
// hence the use of | count 0.
Expand Down
6 changes: 6 additions & 0 deletions clang-tools-extra/test/pp-trace/pp-trace-pragma-general.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ void foo() {

// CHECK: ---
// CHECK-NEXT: - Callback: PragmaDirective
// CHECK-NEXT: Loc: "<built-in>:{{.+}}:1"
// CHECK-NEXT: Introducer: PIK_HashPragma
// CHECK-NEXT: - Callback: PragmaDirective
// CHECK-NEXT: Loc: "<built-in>:{{.+}}:1"
// CHECK-NEXT: Introducer: PIK_HashPragma
// CHECK-NEXT: - Callback: PragmaDirective
// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:3:1"
// CHECK-NEXT: Introducer: PIK_HashPragma
// CHECK-NEXT: - Callback: PragmaDiagnosticPush
Expand Down
8 changes: 7 additions & 1 deletion clang-tools-extra/test/pp-trace/pp-trace-pragma-ms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@

// CHECK: ---
// CHECK-NEXT: - Callback: PragmaDirective
// CHECK-NEXT: Loc: "<built-in>:{{.+}}:1"
// CHECK-NEXT: Introducer: PIK_HashPragma
// CHECK-NEXT: - Callback: PragmaDirective
// CHECK-NEXT: Loc: "<built-in>:{{.+}}:1"
// CHECK-NEXT: Introducer: PIK_HashPragma
// CHECK-NEXT: - Callback: PragmaDirective
// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:3:1"
// CHECK-NEXT: Introducer: PIK_HashPragma
// CHECK-NEXT: - Callback: PragmaComment
Expand Down Expand Up @@ -67,7 +73,7 @@
// CHECK-NEXT: Introducer: PIK_HashPragma
// CHECK-NEXT: - Callback: PragmaMessage
// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:13:9"
// CHECK-NEXT: Namespace:
// CHECK-NEXT: Namespace:
// CHECK-NEXT: Kind: PMK_Message
// CHECK-NEXT: Str: message argument
// CHECK-NEXT: - Callback: PragmaDirective
Expand Down
6 changes: 6 additions & 0 deletions clang-tools-extra/test/pp-trace/pp-trace-pragma-opencl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@

// CHECK: ---
// CHECK-NEXT: - Callback: PragmaDirective
// CHECK-NEXT: Loc: "<built-in>:{{.+}}:1"
// CHECK-NEXT: Introducer: PIK_HashPragma
// CHECK-NEXT: - Callback: PragmaDirective
// CHECK-NEXT: Loc: "<built-in>:{{.+}}:1"
// CHECK-NEXT: Introducer: PIK_HashPragma
// CHECK-NEXT: - Callback: PragmaDirective
// CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-opencl.cpp:3:1"
// CHECK-NEXT: Introducer: PIK_HashPragma
// CHECK-NEXT: - Callback: PragmaOpenCLExtension
Expand Down
1 change: 1 addition & 0 deletions clang/cmake/caches/Release.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ set(LLVM_ENABLE_PROJECTS ${STAGE1_PROJECTS} CACHE STRING "")
# stage2-instrumented and Final Stage Config:
# Options that need to be set in both the instrumented stage (if we are doing
# a pgo build) and the final stage.
set_instrument_and_final_stage_var(CMAKE_POSITION_INDEPENDENT_CODE "ON" STRING)
set_instrument_and_final_stage_var(LLVM_ENABLE_LTO "${LLVM_RELEASE_ENABLE_LTO}" STRING)
if (LLVM_RELEASE_ENABLE_LTO)
set_instrument_and_final_stage_var(LLVM_ENABLE_LLD "ON" BOOL)
Expand Down
22 changes: 22 additions & 0 deletions clang/docs/LanguageExtensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5572,3 +5572,25 @@ but the expression has no runtime effects.
Type- and value-dependent expressions are not supported yet.
This facility is designed to aid with testing name lookup machinery.
Predefined Macros
=================
`__GCC_DESTRUCTIVE_SIZE` and `__GCC_CONSTRUCTIVE_SIZE`
------------------------------------------------------
Specify the mimum offset between two objects to avoid false sharing and the
maximum size of contiguous memory to promote true sharing, respectively. These
macros are predefined in all C and C++ language modes, but can be redefined on
the command line with ``-D`` to specify different values as needed or can be
undefined on the command line with ``-U`` to disable support for the feature.
**Note: the values the macros expand to are not guaranteed to be stable. They
are are affected by architectures and CPU tuning flags, can change between
releases of Clang and will not match the values defined by other compilers such
as GCC.**
Compiling different TUs depending on these flags (including use of
``std::hardware_constructive_interference`` or
``std::hardware_destructive_interference``) with different compilers, macro
definitions, or architecture flags will lead to ODR violations and should be
avoided.
15 changes: 15 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,18 @@ C++ Language Changes
--------------------
- Implemented ``_BitInt`` literal suffixes ``__wb`` or ``__WB`` as a Clang extension with ``unsigned`` modifiers also allowed. (#GH85223).

C++17 Feature Support
^^^^^^^^^^^^^^^^^^^^^
- Clang now exposes ``__GCC_DESTRUCTIVE_SIZE`` and ``__GCC_CONSTRUCTIVE_SIZE``
predefined macros to support standard library implementations of
``std::hardware_destructive_interference_size`` and
``std::hardware_constructive_interference_size``, respectively. These macros
are predefined in all C and C++ language modes. The values the macros
expand to are not stable between releases of Clang and do not need to match
the values produced by GCC, so these macros should not be used from header
files because they may not be stable across multiple TUs (the values may vary
based on compiler version as well as CPU tuning). #GH60174

C++20 Feature Support
^^^^^^^^^^^^^^^^^^^^^

Expand Down Expand Up @@ -628,6 +640,9 @@ Arm and AArch64 Support
* Arm Cortex-A78AE (cortex-a78ae).
* Arm Cortex-A520AE (cortex-a520ae).
* Arm Cortex-A720AE (cortex-a720ae).
* Arm Neoverse-N3 (neoverse-n3).
* Arm Neoverse-V3 (neoverse-v3).
* Arm Neoverse-V3AE (neoverse-v3ae).

Android Support
^^^^^^^^^^^^^^^
Expand Down
22 changes: 21 additions & 1 deletion clang/include/clang/APINotes/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -675,14 +675,21 @@ class TagInfo : public CommonTypeInfo {
LLVM_PREFERRED_TYPE(bool)
unsigned IsFlagEnum : 1;

LLVM_PREFERRED_TYPE(bool)
unsigned SwiftCopyableSpecified : 1;
LLVM_PREFERRED_TYPE(bool)
unsigned SwiftCopyable : 1;

public:
std::optional<std::string> SwiftImportAs;
std::optional<std::string> SwiftRetainOp;
std::optional<std::string> SwiftReleaseOp;

std::optional<EnumExtensibilityKind> EnumExtensibility;

TagInfo() : HasFlagEnum(0), IsFlagEnum(0) {}
TagInfo()
: HasFlagEnum(0), IsFlagEnum(0), SwiftCopyableSpecified(false),
SwiftCopyable(false) {}

std::optional<bool> isFlagEnum() const {
if (HasFlagEnum)
Expand All @@ -694,6 +701,15 @@ class TagInfo : public CommonTypeInfo {
IsFlagEnum = Value.value_or(false);
}

std::optional<bool> isSwiftCopyable() const {
return SwiftCopyableSpecified ? std::optional<bool>(SwiftCopyable)
: std::nullopt;
}
void setSwiftCopyable(std::optional<bool> Value) {
SwiftCopyableSpecified = Value.has_value();
SwiftCopyable = Value.value_or(false);
}

TagInfo &operator|=(const TagInfo &RHS) {
static_cast<CommonTypeInfo &>(*this) |= RHS;

Expand All @@ -710,6 +726,9 @@ class TagInfo : public CommonTypeInfo {
if (!EnumExtensibility)
EnumExtensibility = RHS.EnumExtensibility;

if (!SwiftCopyableSpecified)
setSwiftCopyable(RHS.isSwiftCopyable());

return *this;
}

Expand All @@ -724,6 +743,7 @@ inline bool operator==(const TagInfo &LHS, const TagInfo &RHS) {
LHS.SwiftRetainOp == RHS.SwiftRetainOp &&
LHS.SwiftReleaseOp == RHS.SwiftReleaseOp &&
LHS.isFlagEnum() == RHS.isFlagEnum() &&
LHS.isSwiftCopyable() == RHS.isSwiftCopyable() &&
LHS.EnumExtensibility == RHS.EnumExtensibility;
}

Expand Down
10 changes: 10 additions & 0 deletions clang/include/clang/Basic/TargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include <cassert>
#include <optional>
#include <string>
#include <utility>
#include <vector>

namespace llvm {
Expand Down Expand Up @@ -1792,6 +1793,15 @@ class TargetInfo : public TransferrableTargetInfo,
/// Whether to support HIP image/texture API's.
virtual bool hasHIPImageSupport() const { return true; }

/// The first value in the pair is the minimum offset between two objects to
/// avoid false sharing (destructive interference). The second value in the
/// pair is maximum size of contiguous memory to promote true sharing
/// (constructive interference). Neither of these values are considered part
/// of the ABI and can be changed by targets at any time.
virtual std::pair<unsigned, unsigned> hardwareInterferenceSizes() const {
return std::make_pair(64, 64);
}

protected:
/// Copy type and layout related info.
void copyAuxTarget(const TargetInfo *Aux);
Expand Down
27 changes: 14 additions & 13 deletions clang/include/clang/Basic/arm_sve.td
Original file line number Diff line number Diff line change
Expand Up @@ -1961,19 +1961,20 @@ def SVPSEL_D : SInst<"svpsel_lane_b64", "PPPm", "Pl", MergeNone, "", [IsStreamin

// Standalone sve2.1 builtins
let TargetGuard = "sve2p1" in {
def SVORQV : SInst<"svorqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_orqv", [IsReductionQV]>;
def SVEORQV : SInst<"sveorqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eorqv", [IsReductionQV]>;
def SVADDQV : SInst<"svaddqv[_{d}]", "{Pd", "hfdcsilUcUsUiUl", MergeNone, "aarch64_sve_addqv", [IsReductionQV]>;
def SVANDQV : SInst<"svandqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_andqv", [IsReductionQV]>;
def SVSMAXQV : SInst<"svmaxqv[_{d}]", "{Pd", "csil", MergeNone, "aarch64_sve_smaxqv", [IsReductionQV]>;
def SVUMAXQV : SInst<"svmaxqv[_{d}]", "{Pd", "UcUsUiUl", MergeNone, "aarch64_sve_umaxqv", [IsReductionQV]>;
def SVSMINQV : SInst<"svminqv[_{d}]", "{Pd", "csil", MergeNone, "aarch64_sve_sminqv", [IsReductionQV]>;
def SVUMINQV : SInst<"svminqv[_{d}]", "{Pd", "UcUsUiUl", MergeNone, "aarch64_sve_uminqv", [IsReductionQV]>;

def SVFMAXNMQV: SInst<"svmaxnmqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fmaxnmqv", [IsReductionQV]>;
def SVFMINNMQV: SInst<"svminnmqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fminnmqv", [IsReductionQV]>;
def SVFMAXQV: SInst<"svmaxqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fmaxqv", [IsReductionQV]>;
def SVFMINQV: SInst<"svminqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fminqv", [IsReductionQV]>;
def SVORQV : SInst<"svorqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_orqv", [IsReductionQV]>;
def SVEORQV : SInst<"sveorqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eorqv", [IsReductionQV]>;
def SVADDQV : SInst<"svaddqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_addqv", [IsReductionQV]>;
def SVANDQV : SInst<"svandqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_andqv", [IsReductionQV]>;
def SVSMAXQV : SInst<"svmaxqv[_{d}]", "{Pd", "csil", MergeNone, "aarch64_sve_smaxqv", [IsReductionQV]>;
def SVUMAXQV : SInst<"svmaxqv[_{d}]", "{Pd", "UcUsUiUl", MergeNone, "aarch64_sve_umaxqv", [IsReductionQV]>;
def SVSMINQV : SInst<"svminqv[_{d}]", "{Pd", "csil", MergeNone, "aarch64_sve_sminqv", [IsReductionQV]>;
def SVUMINQV : SInst<"svminqv[_{d}]", "{Pd", "UcUsUiUl", MergeNone, "aarch64_sve_uminqv", [IsReductionQV]>;

def SVFADDQV : SInst<"svaddqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_faddqv", [IsReductionQV]>;
def SVFMAXNMQV : SInst<"svmaxnmqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fmaxnmqv", [IsReductionQV]>;
def SVFMINNMQV : SInst<"svminnmqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fminnmqv", [IsReductionQV]>;
def SVFMAXQV : SInst<"svmaxqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fmaxqv", [IsReductionQV]>;
def SVFMINQV : SInst<"svminqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fminqv", [IsReductionQV]>;
}

let TargetGuard = "sve2p1|sme2" in {
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -4881,6 +4881,8 @@ def msimd128 : Flag<["-"], "msimd128">, Group<m_wasm_Features_Group>;
def mno_simd128 : Flag<["-"], "mno-simd128">, Group<m_wasm_Features_Group>;
def mrelaxed_simd : Flag<["-"], "mrelaxed-simd">, Group<m_wasm_Features_Group>;
def mno_relaxed_simd : Flag<["-"], "mno-relaxed-simd">, Group<m_wasm_Features_Group>;
def mhalf_precision : Flag<["-"], "mhalf-precision">, Group<m_wasm_Features_Group>;
def mno_half_precision : Flag<["-"], "mno-half-precision">, Group<m_wasm_Features_Group>;
def mnontrapping_fptoint : Flag<["-"], "mnontrapping-fptoint">, Group<m_wasm_Features_Group>;
def mno_nontrapping_fptoint : Flag<["-"], "mno-nontrapping-fptoint">, Group<m_wasm_Features_Group>;
def msign_ext : Flag<["-"], "msign-ext">, Group<m_wasm_Features_Group>;
Expand Down
14 changes: 5 additions & 9 deletions clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,15 +225,11 @@ class StoreManager {
/// invalidated. This should include any regions explicitly invalidated
/// even if they do not currently have bindings. Pass \c NULL if this
/// information will not be used.
virtual StoreRef invalidateRegions(Store store,
ArrayRef<SVal> Values,
const Expr *E, unsigned Count,
const LocationContext *LCtx,
const CallEvent *Call,
InvalidatedSymbols &IS,
RegionAndSymbolInvalidationTraits &ITraits,
InvalidatedRegions *InvalidatedTopLevel,
InvalidatedRegions *Invalidated) = 0;
virtual StoreRef invalidateRegions(
Store store, ArrayRef<SVal> Values, const Expr *Ex, unsigned Count,
const LocationContext *LCtx, const CallEvent *Call,
InvalidatedSymbols &IS, RegionAndSymbolInvalidationTraits &ITraits,
InvalidatedRegions *TopLevelRegions, InvalidatedRegions *Invalidated) = 0;

/// enterStackFrame - Let the StoreManager to do something when execution
/// engine is about to execute into a callee.
Expand Down
5 changes: 4 additions & 1 deletion clang/lib/APINotes/APINotesFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ const uint16_t VERSION_MAJOR = 0;
/// API notes file minor version number.
///
/// When the format changes IN ANY WAY, this number should be incremented.
const uint16_t VERSION_MINOR = 25; // SwiftImportAs
const uint16_t VERSION_MINOR = 26; // SwiftCopyable

const uint8_t kSwiftCopyable = 1;
const uint8_t kSwiftNonCopyable = 2;

using IdentifierID = llvm::PointerEmbeddedInt<unsigned, 31>;
using IdentifierIDField = llvm::BCVBR<16>;
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/APINotes/APINotesReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,13 @@ class TagTableInfo
Info.EnumExtensibility =
static_cast<EnumExtensibilityKind>((Payload & 0x3) - 1);

uint8_t Copyable =
endian::readNext<uint8_t, llvm::endianness::little>(Data);
if (Copyable == kSwiftNonCopyable)
Info.setSwiftCopyable(std::optional(false));
else if (Copyable == kSwiftCopyable)
Info.setSwiftCopyable(std::optional(true));

unsigned ImportAsLength =
endian::readNext<uint16_t, llvm::endianness::little>(Data);
if (ImportAsLength > 0) {
Expand Down
7 changes: 6 additions & 1 deletion clang/lib/APINotes/APINotesWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1128,7 +1128,7 @@ class TagTableInfo : public CommonTypeTableInfo<TagTableInfo, TagInfo> {
return 2 + (TI.SwiftImportAs ? TI.SwiftImportAs->size() : 0) +
2 + (TI.SwiftRetainOp ? TI.SwiftRetainOp->size() : 0) +
2 + (TI.SwiftReleaseOp ? TI.SwiftReleaseOp->size() : 0) +
1 + getCommonTypeInfoSize(TI);
2 + getCommonTypeInfoSize(TI);
}

void emitUnversionedInfo(raw_ostream &OS, const TagInfo &TI) {
Expand All @@ -1146,6 +1146,11 @@ class TagTableInfo : public CommonTypeTableInfo<TagTableInfo, TagInfo> {

writer.write<uint8_t>(Flags);

if (auto Copyable = TI.isSwiftCopyable())
writer.write<uint8_t>(*Copyable ? kSwiftCopyable : kSwiftNonCopyable);
else
writer.write<uint8_t>(0);

if (auto ImportAs = TI.SwiftImportAs) {
writer.write<uint16_t>(ImportAs->size() + 1);
OS.write(ImportAs->c_str(), ImportAs->size());
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/APINotes/APINotesYAMLCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ struct Tag {
std::optional<EnumExtensibilityKind> EnumExtensibility;
std::optional<bool> FlagEnum;
std::optional<EnumConvenienceAliasKind> EnumConvenienceKind;
std::optional<bool> SwiftCopyable;
};

typedef std::vector<Tag> TagsSeq;
Expand Down Expand Up @@ -452,6 +453,7 @@ template <> struct MappingTraits<Tag> {
IO.mapOptional("EnumExtensibility", T.EnumExtensibility);
IO.mapOptional("FlagEnum", T.FlagEnum);
IO.mapOptional("EnumKind", T.EnumConvenienceKind);
IO.mapOptional("SwiftCopyable", T.SwiftCopyable);
}
};
} // namespace yaml
Expand Down Expand Up @@ -1009,6 +1011,9 @@ class YAMLConverter {
if (Tag.SwiftReleaseOp)
TI.SwiftReleaseOp = Tag.SwiftReleaseOp;

if (Tag.SwiftCopyable)
TI.setSwiftCopyable(Tag.SwiftCopyable);

if (Tag.EnumConvenienceKind) {
if (Tag.EnumExtensibility) {
emitError(
Expand Down
67 changes: 34 additions & 33 deletions clang/lib/AST/Interp/ByteCodeExprGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,18 +110,37 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
if (!this->visit(SubExpr))
return false;

unsigned DerivedOffset = collectBaseOffset(getRecordTy(CE->getType()),
getRecordTy(SubExpr->getType()));
const auto extractRecordDecl = [](QualType Ty) -> const CXXRecordDecl * {
if (const auto *PT = dyn_cast<PointerType>(Ty))
return PT->getPointeeType()->getAsCXXRecordDecl();
return Ty->getAsCXXRecordDecl();
};

// FIXME: We can express a series of non-virtual casts as a single
// GetPtrBasePop op.
QualType CurType = SubExpr->getType();
for (const CXXBaseSpecifier *B : CE->path()) {
if (B->isVirtual()) {
if (!this->emitGetPtrVirtBasePop(extractRecordDecl(B->getType()), CE))
return false;
CurType = B->getType();
} else {
unsigned DerivedOffset = collectBaseOffset(B->getType(), CurType);
if (!this->emitGetPtrBasePop(DerivedOffset, CE))
return false;
CurType = B->getType();
}
}

return this->emitGetPtrBasePop(DerivedOffset, CE);
return true;
}

case CK_BaseToDerived: {
if (!this->visit(SubExpr))
return false;

unsigned DerivedOffset = collectBaseOffset(getRecordTy(SubExpr->getType()),
getRecordTy(CE->getType()));
unsigned DerivedOffset =
collectBaseOffset(SubExpr->getType(), CE->getType());

return this->emitGetPtrDerivedPop(DerivedOffset, CE);
}
Expand Down Expand Up @@ -3529,35 +3548,17 @@ void ByteCodeExprGen<Emitter>::emitCleanup() {

template <class Emitter>
unsigned
ByteCodeExprGen<Emitter>::collectBaseOffset(const RecordType *BaseType,
const RecordType *DerivedType) {
assert(BaseType);
assert(DerivedType);
const auto *FinalDecl = cast<CXXRecordDecl>(BaseType->getDecl());
const RecordDecl *CurDecl = DerivedType->getDecl();
const Record *CurRecord = getRecord(CurDecl);
assert(CurDecl && FinalDecl);

unsigned OffsetSum = 0;
for (;;) {
assert(CurRecord->getNumBases() > 0);
// One level up
for (const Record::Base &B : CurRecord->bases()) {
const auto *BaseDecl = cast<CXXRecordDecl>(B.Decl);

if (BaseDecl == FinalDecl || BaseDecl->isDerivedFrom(FinalDecl)) {
OffsetSum += B.Offset;
CurRecord = B.R;
CurDecl = BaseDecl;
break;
}
}
if (CurDecl == FinalDecl)
break;
}
ByteCodeExprGen<Emitter>::collectBaseOffset(const QualType BaseType,
const QualType DerivedType) {
const auto extractRecordDecl = [](QualType Ty) -> const CXXRecordDecl * {
if (const auto *PT = dyn_cast<PointerType>(Ty))
return PT->getPointeeType()->getAsCXXRecordDecl();
return Ty->getAsCXXRecordDecl();
};
const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType);

assert(OffsetSum > 0);
return OffsetSum;
return Ctx.collectBaseOffset(BaseDecl, DerivedDecl);
}

/// Emit casts from a PrimType to another PrimType.
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/AST/Interp/ByteCodeExprGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,8 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,

bool emitRecordDestruction(const Record *R);
bool emitDestruction(const Descriptor *Desc);
unsigned collectBaseOffset(const RecordType *BaseType,
const RecordType *DerivedType);
unsigned collectBaseOffset(const QualType BaseType,
const QualType DerivedType);

protected:
/// Variable to storage mapping.
Expand Down
21 changes: 15 additions & 6 deletions clang/lib/AST/Interp/ByteCodeStmtGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,14 +189,23 @@ bool ByteCodeStmtGen<Emitter>::visitFunc(const FunctionDecl *F) {
if (!emitFieldInitializer(F, F->Offset, InitExpr))
return false;
} else if (const Type *Base = Init->getBaseClass()) {
// Base class initializer.
// Get This Base and call initializer on it.
const auto *BaseDecl = Base->getAsCXXRecordDecl();
assert(BaseDecl);
const Record::Base *B = R->getBase(BaseDecl);
assert(B);
if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
return false;

if (Init->isBaseVirtual()) {
assert(R->getVirtualBase(BaseDecl));
if (!this->emitGetPtrThisVirtBase(BaseDecl, InitExpr))
return false;

} else {
// Base class initializer.
// Get This Base and call initializer on it.
const Record::Base *B = R->getBase(BaseDecl);
assert(B);
if (!this->emitGetPtrThisBase(B->Offset, InitExpr))
return false;
}

if (!this->visitInitializer(InitExpr))
return false;
if (!this->emitFinishInitPop(InitExpr))
Expand Down
33 changes: 33 additions & 0 deletions clang/lib/AST/Interp/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,3 +262,36 @@ const Function *Context::getOrCreateFunction(const FunctionDecl *FD) {

return Func;
}

unsigned Context::collectBaseOffset(const RecordDecl *BaseDecl,
const RecordDecl *DerivedDecl) const {
assert(BaseDecl);
assert(DerivedDecl);
const auto *FinalDecl = cast<CXXRecordDecl>(BaseDecl);
const RecordDecl *CurDecl = DerivedDecl;
const Record *CurRecord = P->getOrCreateRecord(CurDecl);
assert(CurDecl && FinalDecl);

unsigned OffsetSum = 0;
for (;;) {
assert(CurRecord->getNumBases() > 0);
// One level up
for (const Record::Base &B : CurRecord->bases()) {
const auto *BaseDecl = cast<CXXRecordDecl>(B.Decl);

if (BaseDecl == FinalDecl || BaseDecl->isDerivedFrom(FinalDecl)) {
OffsetSum += B.Offset;
CurRecord = B.R;
CurDecl = BaseDecl;
break;
}
}
if (CurDecl == FinalDecl)
break;

// break;
}

assert(OffsetSum > 0);
return OffsetSum;
}
3 changes: 3 additions & 0 deletions clang/lib/AST/Interp/Context.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ class Context final {
/// Returns the program. This is only needed for unittests.
Program &getProgram() const { return *P.get(); }

unsigned collectBaseOffset(const RecordDecl *BaseDecl,
const RecordDecl *DerivedDecl) const;

private:
/// Runs a function.
bool Run(State &Parent, const Function *Func, APValue &Result);
Expand Down
74 changes: 56 additions & 18 deletions clang/lib/AST/Interp/Descriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,28 +136,66 @@ static void moveArrayDesc(Block *B, const std::byte *Src, std::byte *Dst,
}
}

static void initField(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
bool IsActive, const Descriptor *D,
unsigned FieldOffset) {
bool IsUnion = false; // FIXME
auto *Desc = reinterpret_cast<InlineDescriptor *>(Ptr + FieldOffset) - 1;
Desc->Offset = FieldOffset;
Desc->Desc = D;
Desc->IsInitialized = D->IsArray;
Desc->IsBase = false;
Desc->IsActive = IsActive && !IsUnion;
Desc->IsConst = IsConst || D->IsConst;
Desc->IsFieldMutable = IsMutable || D->IsMutable;

if (auto Fn = D->CtorFn)
Fn(B, Ptr + FieldOffset, Desc->IsConst, Desc->IsFieldMutable,
Desc->IsActive, D);
}

static void initBase(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
bool IsActive, const Descriptor *D, unsigned FieldOffset,
bool IsVirtualBase) {
assert(D);
assert(D->ElemRecord);

bool IsUnion = D->ElemRecord->isUnion();
auto *Desc = reinterpret_cast<InlineDescriptor *>(Ptr + FieldOffset) - 1;
Desc->Offset = FieldOffset;
Desc->Desc = D;
Desc->IsInitialized = D->IsArray;
Desc->IsBase = true;
Desc->IsActive = IsActive && !IsUnion;
Desc->IsConst = IsConst || D->IsConst;
Desc->IsFieldMutable = IsMutable || D->IsMutable;

for (const auto &V : D->ElemRecord->bases())
initBase(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, V.Desc,
V.Offset, false);
for (const auto &F : D->ElemRecord->fields())
initField(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, F.Desc,
F.Offset);

// If this is initializing a virtual base, we do NOT want to consider its
// virtual bases, those are already flattened into the parent record when
// creating it.
if (IsVirtualBase)
return;

for (const auto &V : D->ElemRecord->virtual_bases())
initBase(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, V.Desc,
V.Offset, true);
}

static void ctorRecord(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
bool IsActive, const Descriptor *D) {
const bool IsUnion = D->ElemRecord->isUnion();
auto CtorSub = [=](unsigned SubOff, const Descriptor *F, bool IsBase) {
auto *Desc = reinterpret_cast<InlineDescriptor *>(Ptr + SubOff) - 1;
Desc->Offset = SubOff;
Desc->Desc = F;
Desc->IsInitialized = F->IsArray && !IsBase;
Desc->IsBase = IsBase;
Desc->IsActive = IsActive && !IsUnion;
Desc->IsConst = IsConst || F->IsConst;
Desc->IsFieldMutable = IsMutable || F->IsMutable;
if (auto Fn = F->CtorFn)
Fn(B, Ptr + SubOff, Desc->IsConst, Desc->IsFieldMutable, Desc->IsActive,
F);
};
for (const auto &B : D->ElemRecord->bases())
CtorSub(B.Offset, B.Desc, /*isBase=*/true);
for (const auto &V : D->ElemRecord->bases())
initBase(B, Ptr, IsConst, IsMutable, IsActive, V.Desc, V.Offset, false);
for (const auto &F : D->ElemRecord->fields())
CtorSub(F.Offset, F.Desc, /*isBase=*/false);
initField(B, Ptr, IsConst, IsMutable, IsActive, F.Desc, F.Offset);
for (const auto &V : D->ElemRecord->virtual_bases())
CtorSub(V.Offset, V.Desc, /*isBase=*/true);
initBase(B, Ptr, IsConst, IsMutable, IsActive, V.Desc, V.Offset, true);
}

static void dtorRecord(Block *B, std::byte *Ptr, const Descriptor *D) {
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/AST/Interp/Descriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ struct InlineDescriptor {
InlineDescriptor(const Descriptor *D)
: Offset(sizeof(InlineDescriptor)), IsConst(false), IsInitialized(false),
IsBase(false), IsActive(false), IsFieldMutable(false), Desc(D) {}

void dump() const { dump(llvm::errs()); }
void dump(llvm::raw_ostream &OS) const;
};

/// Describes a memory block created by an allocation site.
Expand Down
29 changes: 27 additions & 2 deletions clang/lib/AST/Interp/Disasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,25 @@ LLVM_DUMP_METHOD void Descriptor::dump(llvm::raw_ostream &OS) const {
OS << " dummy";
}

LLVM_DUMP_METHOD void InlineDescriptor::dump(llvm::raw_ostream &OS) const {
{
ColorScope SC(OS, true, {llvm::raw_ostream::BLUE, true});
OS << "InlineDescriptor " << (const void *)this << "\n";
}
OS << "Offset: " << Offset << "\n";
OS << "IsConst: " << IsConst << "\n";
OS << "IsInitialized: " << IsInitialized << "\n";
OS << "IsBase: " << IsBase << "\n";
OS << "IsActive: " << IsActive << "\n";
OS << "IsFieldMutable: " << IsFieldMutable << "\n";
OS << "Desc: ";
if (Desc)
Desc->dump(OS);
else
OS << "nullptr";
OS << "\n";
}

LLVM_DUMP_METHOD void InterpFrame::dump(llvm::raw_ostream &OS,
unsigned Indent) const {
unsigned Spaces = Indent * 2;
Expand Down Expand Up @@ -251,8 +270,6 @@ LLVM_DUMP_METHOD void Record::dump(llvm::raw_ostream &OS, unsigned Indentation,
++I;
}

// FIXME: Virtual bases.

I = 0;
for (const Record::Field &F : fields()) {
OS.indent(Indent) << "- Field " << I << ": ";
Expand All @@ -263,6 +280,14 @@ LLVM_DUMP_METHOD void Record::dump(llvm::raw_ostream &OS, unsigned Indentation,
OS << ". Offset " << (Offset + F.Offset) << "\n";
++I;
}

I = 0;
for (const Record::Base &B : virtual_bases()) {
OS.indent(Indent) << "- Virtual Base " << I << ". Offset "
<< (Offset + B.Offset) << "\n";
B.R->dump(OS, Indentation + 1, Offset + B.Offset);
++I;
}
}

LLVM_DUMP_METHOD void Block::dump(llvm::raw_ostream &OS) const {
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/AST/Interp/Interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -1366,6 +1366,9 @@ inline bool GetPtrVirtBasePop(InterpState &S, CodePtr OpPC,
const Pointer &Ptr = S.Stk.pop<Pointer>();
if (!CheckNull(S, OpPC, Ptr, CSK_Base))
return false;
if (Ptr.isDummy()) // FIXME: Once we have type info for dummy pointers, this
// needs to go.
return false;
return VirtBaseHelper(S, OpPC, D, Ptr);
}

Expand Down
16 changes: 12 additions & 4 deletions clang/lib/Analysis/FlowSensitive/ASTOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,20 @@ namespace clang::dataflow {

const Expr &ignoreCFGOmittedNodes(const Expr &E) {
const Expr *Current = &E;
if (auto *EWC = dyn_cast<ExprWithCleanups>(Current)) {
Current = EWC->getSubExpr();
const Expr *Last = nullptr;
while (Current != Last) {
Last = Current;
if (auto *EWC = dyn_cast<ExprWithCleanups>(Current)) {
Current = EWC->getSubExpr();
assert(Current != nullptr);
}
if (auto *CE = dyn_cast<ConstantExpr>(Current)) {
Current = CE->getSubExpr();
assert(Current != nullptr);
}
Current = Current->IgnoreParens();
assert(Current != nullptr);
}
Current = Current->IgnoreParens();
assert(Current != nullptr);
return *Current;
}

Expand Down
6 changes: 5 additions & 1 deletion clang/lib/Analysis/FlowSensitive/Transfer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ namespace dataflow {

const Environment *StmtToEnvMap::getEnvironment(const Stmt &S) const {
auto BlockIt = ACFG.getStmtToBlock().find(&ignoreCFGOmittedNodes(S));
assert(BlockIt != ACFG.getStmtToBlock().end());
if (BlockIt == ACFG.getStmtToBlock().end()) {
assert(false);
// Return null to avoid dereferencing the end iterator in non-assert builds.
return nullptr;
}
if (!ACFG.isBlockReachable(*BlockIt->getSecond()))
return nullptr;
if (BlockIt->getSecond()->getBlockID() == CurBlockID)
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Basic/Targets/ARM.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,10 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo {
bool hasBitIntType() const override { return true; }

const char *getBFloat16Mangling() const override { return "u6__bf16"; };

std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {
return std::make_pair(getTriple().isArch64Bit() ? 256 : 64, 64);
}
};

class LLVM_LIBRARY_VISIBILITY ARMleTargetInfo : public ARMTargetInfo {
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Basic/Targets/AVR.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ class LLVM_LIBRARY_VISIBILITY AVRTargetInfo : public TargetInfo {
std::optional<std::string> handleAsmEscapedChar(char EscChar) const override;
StringRef getABI() const override { return ABI; }

std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {
return std::make_pair(32, 32);
}

protected:
std::string CPU;
StringRef ABI;
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Basic/Targets/BPF.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ class LLVM_LIBRARY_VISIBILITY BPFTargetInfo : public TargetInfo {
StringRef CPUName(Name);
return isValidCPUName(CPUName);
}

std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {
return std::make_pair(32, 32);
}
};
} // namespace targets
} // namespace clang
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Basic/Targets/M68k.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ class LLVM_LIBRARY_VISIBILITY M68kTargetInfo : public TargetInfo {
BuiltinVaListKind getBuiltinVaListKind() const override;
bool setCPU(const std::string &Name) override;
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override;

std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {
return std::make_pair(32, 32);
}
};

} // namespace targets
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Basic/Targets/Mips.h
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,10 @@ class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo {

bool validateTarget(DiagnosticsEngine &Diags) const override;
bool hasBitIntType() const override { return true; }

std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {
return std::make_pair(32, 32);
}
};
} // namespace targets
} // namespace clang
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/Basic/Targets/PPC.h
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,10 @@ class LLVM_LIBRARY_VISIBILITY PPC32TargetInfo : public PPCTargetInfo {
// This is the ELF definition
return TargetInfo::PowerABIBuiltinVaList;
}

std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {
return std::make_pair(32, 32);
}
};

// Note: ABI differences may eventually require us to have a separate
Expand Down Expand Up @@ -503,6 +507,10 @@ class LLVM_LIBRARY_VISIBILITY PPC64TargetInfo : public PPCTargetInfo {
return CCCR_Warning;
}
}

std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {
return std::make_pair(128, 128);
}
};

class LLVM_LIBRARY_VISIBILITY AIXPPC32TargetInfo :
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Basic/Targets/RISCV.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ class RISCVTargetInfo : public TargetInfo {
void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override;
bool supportsTargetAttributeTune() const override { return true; }
ParsedTargetAttr parseTargetAttr(StringRef Str) const override;

std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {
return std::make_pair(32, 32);
}
};
class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo {
public:
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Basic/Targets/Sparc.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ class LLVM_LIBRARY_VISIBILITY SparcTargetInfo : public TargetInfo {
CPU = getCPUKind(Name);
return CPU != CK_GENERIC;
}

std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {
return std::make_pair(32, 32);
}
};

// SPARC v8 is the 32-bit mode selected by Triple::sparc.
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Basic/Targets/SystemZ.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,10 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
int getEHDataRegisterNumber(unsigned RegNo) const override {
return RegNo < 4 ? 6 + RegNo : -1;
}

std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {
return std::make_pair(256, 256);
}
};
} // namespace targets
} // namespace clang
Expand Down
11 changes: 11 additions & 0 deletions clang/lib/Basic/Targets/WebAssembly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ bool WebAssemblyTargetInfo::hasFeature(StringRef Feature) const {
return llvm::StringSwitch<bool>(Feature)
.Case("simd128", SIMDLevel >= SIMD128)
.Case("relaxed-simd", SIMDLevel >= RelaxedSIMD)
.Case("half-precision", HasHalfPrecision)
.Case("nontrapping-fptoint", HasNontrappingFPToInt)
.Case("sign-ext", HasSignExt)
.Case("exception-handling", HasExceptionHandling)
Expand Down Expand Up @@ -156,6 +157,7 @@ bool WebAssemblyTargetInfo::initFeatureMap(
Features["reference-types"] = true;
Features["sign-ext"] = true;
Features["tail-call"] = true;
Features["half-precision"] = true;
setSIMDLevel(Features, SIMD128, true);
} else if (CPU == "generic") {
Features["mutable-globals"] = true;
Expand Down Expand Up @@ -216,6 +218,15 @@ bool WebAssemblyTargetInfo::handleTargetFeatures(
HasBulkMemory = false;
continue;
}
if (Feature == "+half-precision") {
SIMDLevel = std::max(SIMDLevel, SIMD128);
HasHalfPrecision = true;
continue;
}
if (Feature == "-half-precision") {
HasHalfPrecision = false;
continue;
}
if (Feature == "+atomics") {
HasAtomics = true;
continue;
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Basic/Targets/WebAssembly.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo {
bool HasReferenceTypes = false;
bool HasExtendedConst = false;
bool HasMultiMemory = false;
bool HasHalfPrecision = false;

std::string ABI;

Expand Down
4 changes: 1 addition & 3 deletions clang/lib/Driver/ToolChains/Gnu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1796,9 +1796,7 @@ selectRISCVMultilib(const MultilibSet &RISCVMultilibSet, StringRef Arch,
}
auto &MLConfigISAInfo = *MLConfigParseResult;

const llvm::RISCVISAInfo::OrderedExtensionMap &MLConfigArchExts =
MLConfigISAInfo->getExtensions();
for (auto MLConfigArchExt : MLConfigArchExts) {
for (auto &MLConfigArchExt : MLConfigISAInfo->getExtensions()) {
auto ExtName = MLConfigArchExt.first;
NewMultilib.flag(Twine("-", ExtName).str());

Expand Down
26 changes: 7 additions & 19 deletions clang/lib/Format/TokenAnnotator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4834,10 +4834,8 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
Right.is(TT_TemplateOpener)) {
return true;
}
if (Left.is(tok::identifier) && Right.is(tok::numeric_constant) &&
Right.TokenText[0] == '.') {
return false;
}
if (Left.Tok.getIdentifierInfo() && Right.is(tok::numeric_constant))
return Right.TokenText[0] != '.';
} else if (Style.isProto()) {
if (Right.is(tok::period) &&
Left.isOneOf(Keywords.kw_optional, Keywords.kw_required,
Expand Down Expand Up @@ -5266,21 +5264,11 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
return true;
}
if (Left.is(TT_UnaryOperator)) {
if (Right.isNot(tok::l_paren)) {
// The alternative operators for ~ and ! are "compl" and "not".
// If they are used instead, we do not want to combine them with
// the token to the right, unless that is a left paren.
if (Left.is(tok::exclaim) && Left.TokenText == "not")
return true;
if (Left.is(tok::tilde) && Left.TokenText == "compl")
return true;
// Lambda captures allow for a lone &, so "&]" needs to be properly
// handled.
if (Left.is(tok::amp) && Right.is(tok::r_square))
return Style.SpacesInSquareBrackets;
}
return (Style.SpaceAfterLogicalNot && Left.is(tok::exclaim)) ||
Right.is(TT_BinaryOperator);
// Lambda captures allow for a lone &, so "&]" needs to be properly
// handled.
if (Left.is(tok::amp) && Right.is(tok::r_square))
return Style.SpacesInSquareBrackets;
return Style.SpaceAfterLogicalNot && Left.is(tok::exclaim);
}

// If the next token is a binary operator or a selector name, we have
Expand Down
39 changes: 18 additions & 21 deletions clang/lib/Format/WhitespaceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,13 @@ const tooling::Replacements &WhitespaceManager::generateReplacements() {
void WhitespaceManager::calculateLineBreakInformation() {
Changes[0].PreviousEndOfTokenColumn = 0;
Change *LastOutsideTokenChange = &Changes[0];
for (unsigned i = 1, e = Changes.size(); i != e; ++i) {
for (unsigned I = 1, e = Changes.size(); I != e; ++I) {
auto &C = Changes[I];
auto &P = Changes[I - 1];
SourceLocation OriginalWhitespaceStart =
Changes[i].OriginalWhitespaceRange.getBegin();
C.OriginalWhitespaceRange.getBegin();
SourceLocation PreviousOriginalWhitespaceEnd =
Changes[i - 1].OriginalWhitespaceRange.getEnd();
P.OriginalWhitespaceRange.getEnd();
unsigned OriginalWhitespaceStartOffset =
SourceMgr.getFileOffset(OriginalWhitespaceStart);
unsigned PreviousOriginalWhitespaceEndOffset =
Expand Down Expand Up @@ -167,31 +169,26 @@ void WhitespaceManager::calculateLineBreakInformation() {
// line of the token.
auto NewlinePos = Text.find_first_of('\n');
if (NewlinePos == StringRef::npos) {
Changes[i - 1].TokenLength = OriginalWhitespaceStartOffset -
PreviousOriginalWhitespaceEndOffset +
Changes[i].PreviousLinePostfix.size() +
Changes[i - 1].CurrentLinePrefix.size();
P.TokenLength = OriginalWhitespaceStartOffset -
PreviousOriginalWhitespaceEndOffset +
C.PreviousLinePostfix.size() + P.CurrentLinePrefix.size();
} else {
Changes[i - 1].TokenLength =
NewlinePos + Changes[i - 1].CurrentLinePrefix.size();
P.TokenLength = NewlinePos + P.CurrentLinePrefix.size();
}

// If there are multiple changes in this token, sum up all the changes until
// the end of the line.
if (Changes[i - 1].IsInsideToken && Changes[i - 1].NewlinesBefore == 0) {
LastOutsideTokenChange->TokenLength +=
Changes[i - 1].TokenLength + Changes[i - 1].Spaces;
} else {
LastOutsideTokenChange = &Changes[i - 1];
}
if (P.IsInsideToken && P.NewlinesBefore == 0)
LastOutsideTokenChange->TokenLength += P.TokenLength + P.Spaces;
else
LastOutsideTokenChange = &P;

Changes[i].PreviousEndOfTokenColumn =
Changes[i - 1].StartOfTokenColumn + Changes[i - 1].TokenLength;
C.PreviousEndOfTokenColumn = P.StartOfTokenColumn + P.TokenLength;

Changes[i - 1].IsTrailingComment =
(Changes[i].NewlinesBefore > 0 || Changes[i].Tok->is(tok::eof) ||
(Changes[i].IsInsideToken && Changes[i].Tok->is(tok::comment))) &&
Changes[i - 1].Tok->is(tok::comment) &&
P.IsTrailingComment =
(C.NewlinesBefore > 0 || C.Tok->is(tok::eof) ||
(C.IsInsideToken && C.Tok->is(tok::comment))) &&
P.Tok->is(tok::comment) &&
// FIXME: This is a dirty hack. The problem is that
// BreakableLineCommentSection does comment reflow changes and here is
// the aligning of trailing comments. Consider the case where we reflow
Expand Down
10 changes: 10 additions & 0 deletions clang/lib/Frontend/InitPreprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1308,6 +1308,16 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
Builder.defineMacro("__GCC_ATOMIC_TEST_AND_SET_TRUEVAL", "1");
}

// GCC defines these macros in both C and C++ modes despite them being needed
// mostly for STL implementations in C++.
auto [Destructive, Constructive] = TI.hardwareInterferenceSizes();
Builder.defineMacro("__GCC_DESTRUCTIVE_SIZE", Twine(Destructive));
Builder.defineMacro("__GCC_CONSTRUCTIVE_SIZE", Twine(Constructive));
// We need to use push_macro to allow users to redefine these macros from the
// command line with -D and not issue a -Wmacro-redefined warning.
Builder.append("#pragma push_macro(\"__GCC_DESTRUCTIVE_SIZE\")");
Builder.append("#pragma push_macro(\"__GCC_CONSTRUCTIVE_SIZE\")");

auto addLockFreeMacros = [&](const llvm::Twine &Prefix) {
// Used by libc++ and libstdc++ to implement ATOMIC_<foo>_LOCK_FREE.
#define DEFINE_LOCK_FREE_MACRO(TYPE, Type) \
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/Headers/cpuid.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#ifndef __CPUID_H
#define __CPUID_H

#if !(__x86_64__ || __i386__)
#if !defined(__x86_64__) && !defined(__i386__)
#error this header is for x86 only
#endif

Expand Down Expand Up @@ -256,7 +256,7 @@
#define bit_AVX10_256 0x00020000
#define bit_AVX10_512 0x00040000

#if __i386__
#ifdef __i386__
#define __cpuid(__leaf, __eax, __ebx, __ecx, __edx) \
__asm("cpuid" : "=a"(__eax), "=b" (__ebx), "=c"(__ecx), "=d"(__edx) \
: "0"(__leaf))
Expand Down Expand Up @@ -285,7 +285,7 @@ static __inline unsigned int __get_cpuid_max (unsigned int __leaf,
unsigned int *__sig)
{
unsigned int __eax, __ebx, __ecx, __edx;
#if __i386__
#ifdef __i386__
int __cpuid_supported;

__asm(" pushfl\n"
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/Sema/SemaAPINotes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,11 @@ static void ProcessAPINotes(Sema &S, TagDecl *D, const api_notes::TagInfo &Info,
D->addAttr(
SwiftAttrAttr::Create(S.Context, "release:" + ReleaseOp.value()));

if (auto Copyable = Info.isSwiftCopyable()) {
if (!*Copyable)
D->addAttr(SwiftAttrAttr::Create(S.Context, "~Copyable"));
}

if (auto Extensibility = Info.EnumExtensibility) {
using api_notes::EnumExtensibilityKind;
bool ShouldAddAttribute = (*Extensibility != EnumExtensibilityKind::None);
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ std::optional<bool> isUncounted(const clang::CXXRecordDecl* Class);
/// class, false if not, std::nullopt if inconclusive.
std::optional<bool> isUncountedPtr(const clang::Type* T);

/// \returns true if Name is a RefPtr, Ref, or its variant, false if not.
bool isRefType(const std::string &Name);

/// \returns true if \p F creates ref-countable object from uncounted parameter,
/// false if not.
bool isCtorOfRefCounted(const clang::FunctionDecl *F);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ class UncountedCallArgsChecker
bool shouldVisitTemplateInstantiations() const { return true; }
bool shouldVisitImplicitCode() const { return false; }

bool TraverseDecl(Decl *D) {
if (isa<ClassTemplateDecl>(D) && isRefType(safeGetName(D)))
return true;
return RecursiveASTVisitor<LocalVisitor>::TraverseDecl(D);
}

bool VisitCallExpr(const CallExpr *CE) {
Checker->visitCallExpr(CE);
return true;
Expand Down
4 changes: 4 additions & 0 deletions clang/test/APINotes/Inputs/Headers/SwiftImportAs.apinotes
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@ Tags:
SwiftImportAs: reference
SwiftReleaseOp: RCRelease
SwiftRetainOp: RCRetain
- Name: NonCopyableType
SwiftCopyable: false
- Name: CopyableType
SwiftCopyable: true
3 changes: 3 additions & 0 deletions clang/test/APINotes/Inputs/Headers/SwiftImportAs.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ struct RefCountedType { int value; };

inline void RCRetain(RefCountedType *x) { x->value++; }
inline void RCRelease(RefCountedType *x) { x->value--; }

struct NonCopyableType { int value; };
struct CopyableType { int value; };
10 changes: 10 additions & 0 deletions clang/test/APINotes/swift-import-as.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers %s -x c++
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter ImmortalRefType | FileCheck -check-prefix=CHECK-IMMORTAL %s
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter RefCountedType | FileCheck -check-prefix=CHECK-REF-COUNTED %s
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter NonCopyableType | FileCheck -check-prefix=CHECK-NON-COPYABLE %s
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter CopyableType | FileCheck -check-prefix=CHECK-COPYABLE %s

#include <SwiftImportAs.h>

Expand All @@ -14,3 +16,11 @@
// CHECK-REF-COUNTED: SwiftAttrAttr {{.+}} <<invalid sloc>> "import_reference"
// CHECK-REF-COUNTED: SwiftAttrAttr {{.+}} <<invalid sloc>> "retain:RCRetain"
// CHECK-REF-COUNTED: SwiftAttrAttr {{.+}} <<invalid sloc>> "release:RCRelease"

// CHECK-NON-COPYABLE: Dumping NonCopyableType:
// CHECK-NON-COPYABLE-NEXT: CXXRecordDecl {{.+}} imported in SwiftImportAs {{.+}} struct NonCopyableType
// CHECK-NON-COPYABLE: SwiftAttrAttr {{.+}} <<invalid sloc>> "~Copyable"

// CHECK-COPYABLE: Dumping CopyableType:
// CHECK-COPYABLE-NEXT: CXXRecordDecl {{.+}} imported in SwiftImportAs {{.+}} struct CopyableType
// CHECK-COPYABLE-NOT: SwiftAttrAttr
16 changes: 16 additions & 0 deletions clang/test/AST/Interp/cxx23.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,19 @@ struct check_ice {
};
};
static_assert(check_ice<42>::x == 42);


namespace VirtualBases {
namespace One {
struct U { int n; };
struct V : U { int n; };
struct A : virtual V { int n; };
struct Aa { int n; };
struct B : virtual A, Aa {};
struct C : virtual A, Aa {};
struct D : B, C {};

/// Calls the constructor of D.
D d;
}
}
79 changes: 79 additions & 0 deletions clang/test/AST/Interp/records.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1330,3 +1330,82 @@ namespace UnnamedBitFields {
static_assert(a.f == 1.0, "");
static_assert(a.c == 'a', "");
}

/// FIXME: This still doesn't work in the new interpreter because
/// we lack type information for dummy pointers.
namespace VirtualBases {
/// This used to crash.
namespace One {
class A {
protected:
int x;
};
class B : public virtual A {
public:
int getX() { return x; } // ref-note {{declared here}}
};

class DV : virtual public B{};

void foo() {
DV b;
int a[b.getX()]; // both-warning {{variable length arrays}} \
// ref-note {{non-constexpr function 'getX' cannot be used}}
}
}

namespace Two {
struct U { int n; };
struct A : virtual U { int n; };
struct B : A {};
B a;
static_assert((U*)(A*)(&a) == (U*)(&a), "");

struct C : virtual A {};
struct D : B, C {};
D d;
constexpr B *p = &d;
constexpr C *q = &d;
static_assert((A*)p == (A*)q, ""); // both-error {{failed}}
}

namespace Three {
struct U { int n; };
struct V : U { int n; };
struct A : virtual V { int n; };
struct Aa { int n; };
struct B : virtual A, Aa {};

struct C : virtual A, Aa {};

struct D : B, C {};

D d;

constexpr B *p = &d;
constexpr C *q = &d;

static_assert((void*)p != (void*)q, "");
static_assert((A*)p == (A*)q, "");
static_assert((Aa*)p != (Aa*)q, "");

constexpr V *v = p;
constexpr V *w = q;
constexpr V *x = (A*)p;
static_assert(v == w, "");
static_assert(v == x, "");

static_assert((U*)&d == p, "");
static_assert((U*)&d == q, "");
static_assert((U*)&d == v, "");
static_assert((U*)&d == w, "");
static_assert((U*)&d == x, "");

struct X {};
struct Y1 : virtual X {};
struct Y2 : X {};
struct Z : Y1, Y2 {};
Z z;
static_assert((X*)(Y1*)&z != (X*)(Y2*)&z, "");
}
}
4 changes: 2 additions & 2 deletions clang/test/AST/ast-dump-macro-json.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ void BLAP(foo, __COUNTER__)(void);
// CHECK-NEXT: "spellingLoc": {
// CHECK-NEXT: "offset": {{[0-9]+}},
// CHECK-NEXT: "file": "<scratch space>",
// CHECK-NEXT: "line": 3,
// CHECK-NEXT: "line": 5,
// CHECK-NEXT: "col": 1,
// CHECK-NEXT: "tokLen": 4
// CHECK-NEXT: },
Expand Down Expand Up @@ -169,7 +169,7 @@ void BLAP(foo, __COUNTER__)(void);
// CHECK-NEXT: "spellingLoc": {
// CHECK-NEXT: "offset": {{[0-9]+}},
// CHECK-NEXT: "file": "<scratch space>",
// CHECK-NEXT: "line": 5,
// CHECK-NEXT: "line": 7,
// CHECK-NEXT: "col": 1,
// CHECK-NEXT: "tokLen": 4
// CHECK-NEXT: },
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Analysis/Checkers/WebKit/call-args.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ namespace ref_counted {
void consume_ref_counted(Ref<RefCountable>) {}

void foo() {
consume_refcntbl(provide_ref_counted().get());
consume_refcntbl(provide_ref_counted().ptr());
// no warning
}
}
Expand Down
67 changes: 52 additions & 15 deletions clang/test/Analysis/Checkers/WebKit/mock-types.h
Original file line number Diff line number Diff line change
@@ -1,24 +1,61 @@
#ifndef mock_types_1103988513531
#define mock_types_1103988513531

template <typename T> struct Ref {
T *t;
template<typename T>
struct RawPtrTraits {
using StorageType = T*;

Ref() : t{} {};
Ref(T &t)
: t(t) {
if (t)
t->ref();
template<typename U>
static T* exchange(StorageType& ptr, U&& newValue)
{
StorageType oldValue = static_cast<StorageType&&>(ptr);
ptr = static_cast<U&&>(newValue);
return oldValue;
}
~Ref() {
if (t)
t->deref();

static void swap(StorageType& a, StorageType& b)
{
StorageType temp = static_cast<StorageType&&>(a);
a = static_cast<StorageType&&>(b);
b = static_cast<StorageType&&>(temp);
}
T *get() { return t; }
T *ptr() { return t; }
T *operator->() { return t; }
operator const T &() const { return *t; }
operator T &() { return *t; }
static T* unwrap(const StorageType& ptr) { return ptr; }
};

template<typename T> struct DefaultRefDerefTraits {
static T* refIfNotNull(T* ptr)
{
if (ptr)
ptr->ref();
return ptr;
}

static T& ref(T& ref)
{
ref.ref();
return ref;
}

static void derefIfNotNull(T* ptr)
{
if (ptr)
ptr->deref();
}
};

template <typename T, typename PtrTraits = RawPtrTraits<T>, typename RefDerefTraits = DefaultRefDerefTraits<T>> struct Ref {
typename PtrTraits::StorageType t;

Ref() : t{} {};
Ref(T &t) : t(RefDerefTraits::refIfNotNull(t)) { }
Ref(const Ref& o) : t(RefDerefTraits::refIfNotNull(PtrTraits::unwrap(o.t))) { }
~Ref() { RefDerefTraits::derefIfNotNull(PtrTraits::exchange(t, nullptr)); }
T &get() { return *PtrTraits::unwrap(t); }
T *ptr() { return PtrTraits::unwrap(t); }
T *operator->() { return PtrTraits::unwrap(t); }
operator const T &() const { return *PtrTraits::unwrap(t); }
operator T &() { return *PtrTraits::unwrap(t); }
T* leakRef() { PtrTraits::exchange(t, nullptr); }
};

template <typename T> struct RefPtr {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ int f(int coin) {
// RUN: rm -rf %t.output
// RUN: %clang_analyze_cc1 -analyze -analyzer-checker=core -analyzer-output html -o %t.output %s
// RUN: cat %t.output/* | FileCheck %s --match-full-lines
// CHECK: var relevant_lines = {"1": {"3": 1, "4": 1, "5": 1, "6": 1}, "3": {"3": 1, "4": 1, "5": 1, "6": 1, "7": 1}};
// CHECK: var relevant_lines = {"1": {"3": 1, "4": 1, "5": 1, "6": 1}, "4": {"3": 1, "4": 1, "5": 1, "6": 1, "7": 1}};
77 changes: 77 additions & 0 deletions clang/test/CXX/drs/cwg2149.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors -ast-dump | FileCheck %s --check-prefixes CXX98
// 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=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
// 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=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
// 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=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors

#if __cplusplus == 199711L
#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
// cxx98-error@-1 {{variadic macros are a C99 feature}}
#endif

namespace cwg2149 { // cwg2149: 3.1 drafting 2024-04
#if __cplusplus <= 201103L
struct X { int i, j, k; };
#else
struct X { int i, j, k = 42; };
#endif

template<int N>
void f1(const X(&)[N]); // #cwg2149-f1

template<int N>
void f2(const X(&)[N][2]); // #cwg2149-f2

void f() {
X a[] = { 1, 2, 3, 4, 5, 6 };
static_assert(sizeof(a) / sizeof(X) == 2, "");
X b[2] = { { 1, 2, 3 }, { 4, 5, 6 } };
X c[][2] = { 1, 2, 3, 4, 5, 6 };
static_assert(sizeof(c) / sizeof(X[2]) == 1, "");

#if __cplusplus >= 201103L
constexpr X ca[] = { 1, 2, 3, 4, 5, 6 };
constexpr X cb[2] = { { 1, 2, 3 }, { 4, 5, 6 } };
static_assert(ca[0].i == cb[0].i, "");
static_assert(ca[0].j == cb[0].j, "");
static_assert(ca[0].k == cb[0].k, "");
static_assert(ca[1].i == cb[1].i, "");
static_assert(ca[1].j == cb[1].j, "");
static_assert(ca[1].k == cb[1].k, "");

f1({ 1, 2, 3, 4, 5, 6 });
// since-cxx11-error@-1 {{no matching function for call to 'f1'}}
// since-cxx11-note@#cwg2149-f1 {{candidate function [with N = 6] not viable: no known conversion from 'int' to 'const X' for 1st argument}}
f2({ 1, 2, 3, 4, 5, 6 });
// since-cxx11-error@-1 {{no matching function for call to 'f2'}}
// since-cxx11-note@#cwg2149-f2 {{candidate function [with N = 6] not viable: no known conversion from 'int' to 'const X[2]' for 1st argument}}
#endif
}
} // namespace cwg2149

// Constant evaluation is not powerful enough in 98 mode to check for equality
// via static_assert, even with constant folding enabled.

// CXX98: VarDecl {{.+}} a 'X[2]'
// CXX98-NEXT: `-InitListExpr {{.+}} 'X[2]'
// CXX98-NEXT: |-InitListExpr {{.+}} 'X':'cwg2149::X'
// CXX98-NEXT: | |-IntegerLiteral {{.+}} 'int' 1
// CXX98-NEXT: | |-IntegerLiteral {{.+}} 'int' 2
// CXX98-NEXT: | `-IntegerLiteral {{.+}} 'int' 3
// CXX98-NEXT: `-InitListExpr {{.+}} 'X':'cwg2149::X'
// CXX98-NEXT: |-IntegerLiteral {{.+}} 'int' 4
// CXX98-NEXT: |-IntegerLiteral {{.+}} 'int' 5
// CXX98-NEXT: `-IntegerLiteral {{.+}} 'int' 6

// CXX98: VarDecl {{.+}} b 'X[2]'
// CXX98-NEXT: `-InitListExpr {{.+}} 'X[2]'
// CXX98-NEXT: |-InitListExpr {{.+}} 'X':'cwg2149::X'
// CXX98-NEXT: | |-IntegerLiteral {{.+}} 'int' 1
// CXX98-NEXT: | |-IntegerLiteral {{.+}} 'int' 2
// CXX98-NEXT: | `-IntegerLiteral {{.+}} 'int' 3
// CXX98-NEXT: `-InitListExpr {{.+}} 'X':'cwg2149::X'
// CXX98-NEXT: |-IntegerLiteral {{.+}} 'int' 4
// CXX98-NEXT: |-IntegerLiteral {{.+}} 'int' 5
// CXX98-NEXT: `-IntegerLiteral {{.+}} 'int' 6
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@
// CHECK-LABEL: @test_svaddqv_f16(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> [[PG:%.*]])
// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x half> @llvm.aarch64.sve.addqv.v8f16.nxv8f16(<vscale x 8 x i1> [[TMP0]], <vscale x 8 x half> [[OP:%.*]])
// CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x half> @llvm.aarch64.sve.faddqv.v8f16.nxv8f16(<vscale x 8 x i1> [[TMP0]], <vscale x 8 x half> [[OP:%.*]])
// CHECK-NEXT: ret <8 x half> [[TMP1]]
//
// CPP-CHECK-LABEL: @_Z16test_svaddqv_f16u10__SVBool_tu13__SVFloat16_t(
// CPP-CHECK-NEXT: entry:
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> [[PG:%.*]])
// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x half> @llvm.aarch64.sve.addqv.v8f16.nxv8f16(<vscale x 8 x i1> [[TMP0]], <vscale x 8 x half> [[OP:%.*]])
// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <8 x half> @llvm.aarch64.sve.faddqv.v8f16.nxv8f16(<vscale x 8 x i1> [[TMP0]], <vscale x 8 x half> [[OP:%.*]])
// CPP-CHECK-NEXT: ret <8 x half> [[TMP1]]
//
float16x8_t test_svaddqv_f16(svbool_t pg, svfloat16_t op)
Expand All @@ -37,13 +37,13 @@ float16x8_t test_svaddqv_f16(svbool_t pg, svfloat16_t op)
// CHECK-LABEL: @test_svaddqv_f32(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> [[PG:%.*]])
// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.aarch64.sve.addqv.v4f32.nxv4f32(<vscale x 4 x i1> [[TMP0]], <vscale x 4 x float> [[OP:%.*]])
// CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.aarch64.sve.faddqv.v4f32.nxv4f32(<vscale x 4 x i1> [[TMP0]], <vscale x 4 x float> [[OP:%.*]])
// CHECK-NEXT: ret <4 x float> [[TMP1]]
//
// CPP-CHECK-LABEL: @_Z16test_svaddqv_f32u10__SVBool_tu13__SVFloat32_t(
// CPP-CHECK-NEXT: entry:
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> [[PG:%.*]])
// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.aarch64.sve.addqv.v4f32.nxv4f32(<vscale x 4 x i1> [[TMP0]], <vscale x 4 x float> [[OP:%.*]])
// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <4 x float> @llvm.aarch64.sve.faddqv.v4f32.nxv4f32(<vscale x 4 x i1> [[TMP0]], <vscale x 4 x float> [[OP:%.*]])
// CPP-CHECK-NEXT: ret <4 x float> [[TMP1]]
//
float32x4_t test_svaddqv_f32(svbool_t pg, svfloat32_t op)
Expand All @@ -54,13 +54,13 @@ float32x4_t test_svaddqv_f32(svbool_t pg, svfloat32_t op)
// CHECK-LABEL: @test_svaddqv_f64(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> [[PG:%.*]])
// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.aarch64.sve.addqv.v2f64.nxv2f64(<vscale x 2 x i1> [[TMP0]], <vscale x 2 x double> [[OP:%.*]])
// CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.aarch64.sve.faddqv.v2f64.nxv2f64(<vscale x 2 x i1> [[TMP0]], <vscale x 2 x double> [[OP:%.*]])
// CHECK-NEXT: ret <2 x double> [[TMP1]]
//
// CPP-CHECK-LABEL: @_Z16test_svaddqv_f64u10__SVBool_tu13__SVFloat64_t(
// CPP-CHECK-NEXT: entry:
// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> [[PG:%.*]])
// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.aarch64.sve.addqv.v2f64.nxv2f64(<vscale x 2 x i1> [[TMP0]], <vscale x 2 x double> [[OP:%.*]])
// CPP-CHECK-NEXT: [[TMP1:%.*]] = tail call <2 x double> @llvm.aarch64.sve.faddqv.v2f64.nxv2f64(<vscale x 2 x i1> [[TMP0]], <vscale x 2 x double> [[OP:%.*]])
// CPP-CHECK-NEXT: ret <2 x double> [[TMP1]]
//
float64x2_t test_svaddqv_f64(svbool_t pg, svfloat64_t op)
Expand Down
6 changes: 6 additions & 0 deletions clang/test/Driver/aarch64-mcpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,16 @@
// NEOVERSE-V1: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "neoverse-v1"
// RUN: %clang --target=aarch64 -mcpu=neoverse-v2 -### -c %s 2>&1 | FileCheck -check-prefix=NEOVERSE-V2 %s
// NEOVERSE-V2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "neoverse-v2"
// RUN: %clang --target=aarch64 -mcpu=neoverse-v3 -### -c %s 2>&1 | FileCheck -check-prefix=NEOVERSE-V3 %s
// NEOVERSE-V3: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "neoverse-v3"
// RUN: %clang --target=aarch64 -mcpu=neoverse-v3ae -### -c %s 2>&1 | FileCheck -check-prefix=NEOVERSE-V3AE %s
// NEOVERSE-V3AE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "neoverse-v3ae"
// RUN: %clang --target=aarch64 -mcpu=neoverse-n1 -### -c %s 2>&1 | FileCheck -check-prefix=NEOVERSE-N1 %s
// NEOVERSE-N1: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "neoverse-n1"
// RUN: %clang --target=aarch64 -mcpu=neoverse-n2 -### -c %s 2>&1 | FileCheck -check-prefix=NEOVERSE-N2 %s
// NEOVERSE-N2: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "neoverse-n2"
// RUN: %clang --target=aarch64 -mcpu=neoverse-n3 -### -c %s 2>&1 | FileCheck -check-prefix=NEOVERSE-N3 %s
// NEOVERSE-N3: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "neoverse-n3"
// RUN: %clang --target=aarch64 -mcpu=neoverse-512tvb -### -c %s 2>&1 | FileCheck -check-prefix=NEOVERSE-512TVB %s
// NEOVERSE-512TVB: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "neoverse-512tvb"
// RUN: %clang --target=aarch64 -mcpu=cortex-a520 -### -c %s 2>&1 | FileCheck -check-prefix=CORTEX-A520 %s
Expand Down
3 changes: 0 additions & 3 deletions clang/test/Driver/claim-unused.c

This file was deleted.

5 changes: 2 additions & 3 deletions clang/test/Driver/fp-model.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,8 @@

// RUN: %clang -### -Ofast -ffp-model=strict -c %s 2>&1 | FileCheck \
// RUN: --check-prefix=WARN12 %s
// RUN: %clang -### -ffast-math -ffp-model=strict -c %s 2>&1 | FileCheck \
// RUN: --check-prefix=WARN12 %s
// WARN12-NOT: warning: overriding '-ffp-model=strict' option with '-ffp-model=strict' [-Woverriding-option]
// RUN: %clang -### -Werror -ffast-math -ffp-model=strict -c %s
// WARN12: warning: overriding '-ffp-model=strict' option with '-Ofast'

// RUN: %clang -### -ffp-model=strict -fapprox-func -c %s 2>&1 \
// RUN: | FileCheck --check-prefix=WARN13 %s
Expand Down
2 changes: 2 additions & 0 deletions clang/test/Driver/gcc-param.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// RUN: touch %t.o
// RUN: %clang -Werror --param ssp-buffer-size=1 %t.o -###
1 change: 1 addition & 0 deletions clang/test/Driver/hlsl-lang-targets-spirv.hlsl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// REQUIRES: spirv-registered-target
// REQUIRES: directx-registered-target

// Supported targets
//
Expand Down
45 changes: 15 additions & 30 deletions clang/test/Driver/linux-ld.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,21 @@
// General tests that ld invocations on Linux targets sane. Note that we use
// sysroot to make these tests independent of the host system.
//
// RUN: %clang -### %s -no-pie 2>&1 \
// RUN: %clang -### -Werror %s -no-pie 2>&1 \
// RUN: --target=i386-unknown-linux -rtlib=platform --unwindlib=platform \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-LD-32 %s
// CHECK-LD-32-NOT: warning:
// CHECK-LD-32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
// CHECK-LD-32: "{{.*}}/usr/lib/gcc/i386-unknown-linux/10.2.0{{/|\\\\}}crtbegin.o"
// CHECK-LD-32: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/10.2.0"
// CHECK-LD-32: "-L[[SYSROOT]]/usr/lib/gcc/i386-unknown-linux/10.2.0/../../../../i386-unknown-linux/lib"
// CHECK-LD-32: "-L[[SYSROOT]]/lib"
// CHECK-LD-32: "-L[[SYSROOT]]/usr/lib"
//
// RUN: %clang -### %s -no-pie 2>&1 \
// RUN: %clang -### %s -Werror -no-pie 2>&1 \
// RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-LD-64 %s
// CHECK-LD-64-NOT: warning:
// CHECK-LD-64: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
// CHECK-LD-64: "--eh-frame-hdr"
// CHECK-LD-64: "-m" "elf_x86_64"
Expand All @@ -32,11 +30,10 @@
// CHECK-LD-64: "-lc"
// CHECK-LD-64: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
//
// RUN: %clang -### %s -no-pie 2>&1 \
// RUN: %clang -### %s -Werror -no-pie 2>&1 \
// RUN: --target=x86_64-unknown-linux-gnux32 -rtlib=platform --unwindlib=platform \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-LD-X32 %s
// CHECK-LD-X32-NOT: warning:
// CHECK-LD-X32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
// CHECK-LD-X32: "--eh-frame-hdr"
// CHECK-LD-X32: "-m" "elf32_x86_64"
Expand All @@ -45,13 +42,12 @@
// CHECK-LD-X32: "-lc"
// CHECK-LD-X32: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
//
// RUN: %clang -### %s -no-pie 2>&1 \
// RUN: %clang -### %s -Werror -no-pie 2>&1 \
// RUN: --target=x86_64-unknown-linux \
// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: --rtlib=compiler-rt \
// RUN: | FileCheck --check-prefix=CHECK-LD-RT %s
// CHECK-LD-RT-NOT: warning:
// CHECK-LD-RT: "-resource-dir" "[[RESDIR:[^"]*]]"
// CHECK-LD-RT: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
// CHECK-LD-RT: "--eh-frame-hdr"
Expand All @@ -67,13 +63,12 @@
// CHECK-LD-RT: libclang_rt.builtins.a"
// CHECK-LD-RT: "[[RESDIR]]{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-linux{{/|\\\\}}clang_rt.crtend.o"
//
// RUN: %clang -### %s -no-pie 2>&1 \
// RUN: %clang -### %s -Werror -no-pie 2>&1 \
// RUN: --target=i686-unknown-linux \
// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: --rtlib=compiler-rt \
// RUN: | FileCheck --check-prefix=CHECK-LD-RT-I686 %s
// CHECK-LD-RT-I686-NOT: warning:
// CHECK-LD-RT-I686: "-resource-dir" "[[RESDIR:[^"]*]]"
// CHECK-LD-RT-I686: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
// CHECK-LD-RT-I686: "--eh-frame-hdr"
Expand All @@ -89,13 +84,12 @@
// CHECK-LD-RT-I686: libclang_rt.builtins.a"
// CHECK-LD-RT-I686: "[[RESDIR]]{{/|\\\\}}lib{{/|\\\\}}i686-unknown-linux{{/|\\\\}}clang_rt.crtend.o"
//
// RUN: %clang -### %s -no-pie 2>&1 \
// RUN: %clang -### %s -Werror -no-pie 2>&1 \
// RUN: --target=arm-linux-androideabi \
// RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \
// RUN: -resource-dir=%S/Inputs/resource_dir \
// RUN: --rtlib=compiler-rt \
// RUN: | FileCheck --check-prefix=CHECK-LD-RT-ANDROID %s
// CHECK-LD-RT-ANDROID-NOT: warning:
// CHECK-LD-RT-ANDROID: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
// CHECK-LD-RT-ANDROID: "--eh-frame-hdr"
// CHECK-LD-RT-ANDROID: "-m" "armelf_linux_eabi"
Expand All @@ -104,11 +98,10 @@
// CHECK-LD-RT-ANDROID: "-lc"
// CHECK-LD-RT-ANDROID: libclang_rt.builtins.a"
//
// RUN: %clang -### %s -no-pie 2>&1 \
// RUN: %clang -### %s -Werror -no-pie 2>&1 \
// RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-LD-GCC %s
// CHECK-LD-GCC-NOT: warning:
// CHECK-LD-GCC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
// CHECK-LD-GCC: "--eh-frame-hdr"
// CHECK-LD-GCC: "-m" "elf_x86_64"
Expand All @@ -122,12 +115,11 @@
// CHECK-LD-GCC: "-lc"
// CHECK-LD-GCC: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
//
// RUN: %clang -### %s -no-pie 2>&1 \
// RUN: %clang -### %s -Werror -no-pie 2>&1 \
// RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \
// RUN: -static-libgcc \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-LD-64-STATIC-LIBGCC %s
// CHECK-LD-64-STATIC-LIBGCC-NOT: warning:
// CHECK-LD-64-STATIC-LIBGCC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
// CHECK-LD-64-STATIC-LIBGCC: "--eh-frame-hdr"
// CHECK-LD-64-STATIC-LIBGCC: "-m" "elf_x86_64"
Expand Down Expand Up @@ -268,12 +260,10 @@
// CHECK-CLANG-ANDROID-STATIC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
// CHECK-CLANG-ANDROID-STATIC: "--start-group" "{{[^"]*}}{{/|\\\\}}libclang_rt.builtins.a" "-l:libunwind.a" "-lc" "--end-group"
//
// RUN: %clang -### %s 2>&1 \
// RUN: --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \
// RUN: %clang -### %s -Werror --target=x86_64-unknown-linux -rtlib=platform --unwindlib=platform \
// RUN: -static \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-LD-64-STATIC %s
// CHECK-LD-64-STATIC-NOT: warning:
// CHECK-LD-64-STATIC: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
// CHECK-LD-64-STATIC: "--eh-frame-hdr"
// CHECK-LD-64-STATIC: "-m" "elf_x86_64"
Expand Down Expand Up @@ -486,13 +476,12 @@
//
// Test that we can use -stdlib=libc++ in a build system even when it
// occasionally links C code instead of C++ code.
// RUN: %clang -x c -### %s -no-pie 2>&1 \
// RUN: %clang -x c -### %s -Werror -no-pie 2>&1 \
// RUN: --target=x86_64-unknown-linux-gnu \
// RUN: -stdlib=libc++ \
// RUN: -ccc-install-dir %S/Inputs/basic_linux_libcxx_tree/usr/bin \
// RUN: --sysroot=%S/Inputs/basic_linux_libcxx_tree \
// RUN: | FileCheck --check-prefix=CHECK-BASIC-LIBCXX-C-LINK %s
// CHECK-BASIC-LIBCXX-C-LINK-NOT: warning:
// CHECK-BASIC-LIBCXX-C-LINK: "-cc1"
// CHECK-BASIC-LIBCXX-C-LINK: "-isysroot" "[[SYSROOT:[^"]+]]"
// CHECK-BASIC-LIBCXX-C-LINK-NOT: "-internal-isystem" "[[SYSROOT]]/usr/bin/../include/c++/v1"
Expand Down Expand Up @@ -1661,11 +1650,10 @@
// CHECK-MUSL-AARCH64_BE: "-dynamic-linker" "/lib/ld-musl-aarch64_be.so.1"

// Check whether multilib gcc install works fine on Gentoo with gcc-config
// RUN: %clang -### %s -no-pie 2>&1 \
// RUN: %clang -### %s -Werror -no-pie 2>&1 \
// RUN: --target=x86_64-unknown-linux-gnu -rtlib=platform --unwindlib=platform \
// RUN: --sysroot=%S/Inputs/gentoo_linux_gcc_multi_version_tree \
// RUN: | FileCheck --check-prefix=CHECK-LD-GENTOO %s
// CHECK-LD-GENTOO-NOT: warning:
// CHECK-LD-GENTOO: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
// CHECK-LD-GENTOO: "--eh-frame-hdr"
// CHECK-LD-GENTOO: "-m" "elf_x86_64"
Expand All @@ -1676,11 +1664,10 @@
// CHECK-LD-GENTOO: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
// CHECK-LD-GENTOO: "-lc"
// CHECK-LD-GENTOO: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
// RUN: %clang -### %s -no-pie 2>&1 \
// RUN: %clang -### %s -Werror -no-pie 2>&1 \
// RUN: --target=i686-unknown-linux-gnu -rtlib=platform --unwindlib=platform \
// RUN: --sysroot=%S/Inputs/gentoo_linux_gcc_multi_version_tree \
// RUN: | FileCheck --check-prefix=CHECK-LD-GENTOO-32 %s
// CHECK-LD-GENTOO-32-NOT: warning:
// CHECK-LD-GENTOO-32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
// CHECK-LD-GENTOO-32: "--eh-frame-hdr"
// CHECK-LD-GENTOO-32: "-m" "elf_i386"
Expand All @@ -1691,11 +1678,10 @@
// CHECK-LD-GENTOO-32: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
// CHECK-LD-GENTOO-32: "-lc"
// CHECK-LD-GENTOO-32: "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed"
// RUN: %clang -### %s -no-pie 2>&1 \
// RUN: %clang -### %s -Werror -no-pie 2>&1 \
// RUN: --target=x86_64-unknown-linux-gnux32 -rtlib=platform --unwindlib=platform \
// RUN: --sysroot=%S/Inputs/gentoo_linux_gcc_multi_version_tree \
// RUN: | FileCheck --check-prefix=CHECK-LD-GENTOO-X32 %s
// CHECK-LD-GENTOO-X32-NOT: warning:
// CHECK-LD-GENTOO-X32: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
// CHECK-LD-GENTOO-X32: "--eh-frame-hdr"
// CHECK-LD-GENTOO-X32: "-m" "elf32_x86_64"
Expand All @@ -1717,11 +1703,10 @@
// CHECK-LD-RHEL7-DTS: [[SYSROOT]]/usr/lib/gcc/x86_64-redhat-linux/7/../../../../bin/ld

// Check whether gcc7 install works fine on Amazon Linux AMI
// RUN: %clang -### %s -no-pie 2>&1 \
// RUN: %clang -### %s -Werror -no-pie 2>&1 \
// RUN: --target=x86_64-amazon-linux -rtlib=libgcc --unwindlib=platform \
// RUN: --sysroot=%S/Inputs/ami_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-LD-AMI %s
// CHECK-LD-AMI-NOT: warning:
// CHECK-LD-AMI: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
// CHECK-LD-AMI: "--eh-frame-hdr"
// CHECK-LD-AMI: "-m" "elf_x86_64"
Expand Down
6 changes: 6 additions & 0 deletions clang/test/Driver/wasm-features.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@
// RELAXED-SIMD: "-target-feature" "+relaxed-simd"
// NO-RELAXED-SIMD: "-target-feature" "-relaxed-simd"

// RUN: %clang --target=wasm32-unknown-unknown -### %s -mhalf-precision 2>&1 | FileCheck %s -check-prefix=HALF-PRECISION
// RUN: %clang --target=wasm32-unknown-unknown -### %s -mno-half-precision 2>&1 | FileCheck %s -check-prefix=NO-HALF-PRECISION

// HALF-PRECISION: "-target-feature" "+half-precision"
// NO-HALF-PRECISION: "-target-feature" "-half-precision"

// RUN: %clang --target=wasm32-unknown-unknown -### %s -mexception-handling 2>&1 | FileCheck %s -check-prefix=EXCEPTION-HANDLING
// RUN: %clang --target=wasm32-unknown-unknown -### %s -mno-exception-handling 2>&1 | FileCheck %s -check-prefix=NO-EXCEPTION-HANDLING

Expand Down
13 changes: 7 additions & 6 deletions clang/test/Lexer/update_consecutive_macro_address_space.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// RUN: %clang -cc1 -print-stats %s 2>&1 | FileCheck %s
// CHECK: 6 local SLocEntries allocated
// CHECK: 7 local SLocEntries allocated
//
// Verify that the macro arg expansion is split to two file ids, we have 6 file
// ids rather than 5:
// Verify that the macro arg expansion is split to two file ids, we have 7 file
// ids rather than 6:
// 0: invalid file id
// 1: main file
// 2: builtin file
// 3: macro expansion for X
// 4: macro arg expansions for 1
// 5: macro arg expansions for == 2
// 3: scratch space for __GCC_[CON|DE]STRUCTIVE_SIZE macros
// 4: macro expansion for X
// 5: macro arg expansions for 1
// 6: macro arg expansions for == 2
#define X(x) (int)(x);
void func() {
X(1
Expand Down
4 changes: 2 additions & 2 deletions clang/test/Misc/target-invalid-cpu-note.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@

// 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-NEXT: note: valid target CPU values are: cortex-a34, cortex-a35, cortex-a53, cortex-a55, cortex-a510, cortex-a520, cortex-a520ae, cortex-a57, cortex-a65, cortex-a65ae, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, cortex-a77, cortex-a78, cortex-a78ae, cortex-a78c, cortex-a710, cortex-a715, cortex-a720, cortex-a720ae, cortex-r82, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, cortex-x4, neoverse-e1, neoverse-n1, neoverse-n2, neoverse-512tvb, neoverse-v1, neoverse-v2, cyclone, apple-a7, apple-a8, apple-a9, apple-a10, apple-a11, apple-a12, apple-a13, apple-a14, apple-a15, apple-a16, apple-a17, apple-m1, apple-m2, apple-m3, apple-s4, apple-s5, exynos-m3, exynos-m4, exynos-m5, falkor, saphira, kryo, thunderx2t99, thunderx3t110, thunderx, thunderxt88, thunderxt81, thunderxt83, tsv110, a64fx, carmel, ampere1, ampere1a, ampere1b, cobalt-100, grace{{$}}
// AARCH64-NEXT: note: valid target CPU values are: cortex-a34, cortex-a35, cortex-a53, cortex-a55, cortex-a510, cortex-a520, cortex-a520ae, cortex-a57, cortex-a65, cortex-a65ae, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, cortex-a77, cortex-a78, cortex-a78ae, cortex-a78c, cortex-a710, cortex-a715, cortex-a720, cortex-a720ae, cortex-r82, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, cortex-x4, neoverse-e1, neoverse-n1, neoverse-n2, neoverse-n3, neoverse-512tvb, neoverse-v1, neoverse-v2, neoverse-v3, neoverse-v3ae, cyclone, apple-a7, apple-a8, apple-a9, apple-a10, apple-a11, apple-a12, apple-a13, apple-a14, apple-a15, apple-a16, apple-a17, apple-m1, apple-m2, apple-m3, apple-s4, apple-s5, exynos-m3, exynos-m4, exynos-m5, falkor, saphira, kryo, thunderx2t99, thunderx3t110, thunderx, thunderxt88, thunderxt81, thunderxt83, tsv110, a64fx, carmel, ampere1, ampere1a, ampere1b, cobalt-100, grace{{$}}

// RUN: not %clang_cc1 -triple arm64--- -tune-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix TUNE_AARCH64
// TUNE_AARCH64: error: unknown target CPU 'not-a-cpu'
// TUNE_AARCH64-NEXT: note: valid target CPU values are: cortex-a34, cortex-a35, cortex-a53, cortex-a55, cortex-a510, cortex-a520, cortex-a520ae, cortex-a57, cortex-a65, cortex-a65ae, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, cortex-a77, cortex-a78, cortex-a78ae, cortex-a78c, cortex-a710, cortex-a715, cortex-a720, cortex-a720ae, cortex-r82, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, cortex-x4, neoverse-e1, neoverse-n1, neoverse-n2, neoverse-512tvb, neoverse-v1, neoverse-v2, cyclone, apple-a7, apple-a8, apple-a9, apple-a10, apple-a11, apple-a12, apple-a13, apple-a14, apple-a15, apple-a16, apple-a17, apple-m1, apple-m2, apple-m3, apple-s4, apple-s5, exynos-m3, exynos-m4, exynos-m5, falkor, saphira, kryo, thunderx2t99, thunderx3t110, thunderx, thunderxt88, thunderxt81, thunderxt83, tsv110, a64fx, carmel, ampere1, ampere1a, ampere1b, cobalt-100, grace{{$}}
// TUNE_AARCH64-NEXT: note: valid target CPU values are: cortex-a34, cortex-a35, cortex-a53, cortex-a55, cortex-a510, cortex-a520, cortex-a520ae, cortex-a57, cortex-a65, cortex-a65ae, cortex-a72, cortex-a73, cortex-a75, cortex-a76, cortex-a76ae, cortex-a77, cortex-a78, cortex-a78ae, cortex-a78c, cortex-a710, cortex-a715, cortex-a720, cortex-a720ae, cortex-r82, cortex-x1, cortex-x1c, cortex-x2, cortex-x3, cortex-x4, neoverse-e1, neoverse-n1, neoverse-n2, neoverse-n3, neoverse-512tvb, neoverse-v1, neoverse-v2, neoverse-v3, neoverse-v3ae, cyclone, apple-a7, apple-a8, apple-a9, apple-a10, apple-a11, apple-a12, apple-a13, apple-a14, apple-a15, apple-a16, apple-a17, apple-m1, apple-m2, apple-m3, apple-s4, apple-s5, exynos-m3, exynos-m4, exynos-m5, falkor, saphira, kryo, thunderx2t99, thunderx3t110, thunderx, thunderxt88, thunderxt81, thunderxt83, tsv110, a64fx, carmel, ampere1, ampere1a, ampere1b, cobalt-100, grace{{$}}

// RUN: not %clang_cc1 -triple i386--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix X86
// X86: error: unknown target CPU 'not-a-cpu'
Expand Down
2 changes: 0 additions & 2 deletions clang/test/ParserOpenACC/parse-cache-construct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,6 @@ void use() {
#pragma acc cache(Arrs.MemArr[3].array[1:4])
}
for (int i = 0; i < 10; ++i) {
// FIXME: Once we have a new array-section type to represent OpenACC as
// well, change this error message.
// expected-error@+2{{OpenACC sub-array is not allowed here}}
// expected-warning@+1{{OpenACC construct 'cache' not yet implemented, pragma ignored}}
#pragma acc cache(Arrs.MemArr[3:4].array[1:4])
Expand Down
17 changes: 17 additions & 0 deletions clang/test/Preprocessor/hardware_interference.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// RUN: %clang_cc1 -E -dM -D__GCC_CONSTRUCTIVE_SIZE=1000 -D__GCC_DESTRUCTIVE_SIZE=1001 %s -verify -Weverything | FileCheck %s
// RUN: %clang_cc1 -D__GCC_CONSTRUCTIVE_SIZE=1000 -D__GCC_DESTRUCTIVE_SIZE=1001 %s -verify -Weverything
// RUN: %clang_cc1 -E -dM -U__GCC_CONSTRUCTIVE_SIZE -U__GCC_DESTRUCTIVE_SIZE %s -verify -Weverything | FileCheck --check-prefix DISABLED %s
// expected-no-diagnostics

// Validate that we can set a new value on the command line without issuing any
// diagnostics and that we can disabled the macro on the command line without
// issuing any diagnostics.

// CHECK: #define __GCC_CONSTRUCTIVE_SIZE 1000
// CHECK: #define __GCC_DESTRUCTIVE_SIZE 1001
// DISABLED-NOT: __GCC_CONSTRUCTIVE_SIZE
// DISABLED-NOT: __GCC_DESTRUCTIVE_SIZE

int main() {
return 0;
}
12 changes: 7 additions & 5 deletions clang/test/Preprocessor/init-aarch64.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@
// AARCH64-NEXT: #define __FP_FAST_FMA 1
// AARCH64-NEXT: #define __FP_FAST_FMAF 1
// AARCH64-NEXT: #define __GCC_ASM_FLAG_OUTPUTS__ 1
// AARCH64-NEXT: #define __GCC_CONSTRUCTIVE_SIZE {{.+}}
// AARCH64-NEXT: #define __GCC_DESTRUCTIVE_SIZE {{.+}}
// AARCH64-NEXT: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
// AARCH64-NEXT: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16 1
// AARCH64-NEXT: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
Expand Down Expand Up @@ -220,11 +222,11 @@
// AARCH64-NEXT: #define __LONG_MAX__ 9223372036854775807L
// AARCH64-NEXT: #define __LONG_WIDTH__ 64
// 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 __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_MATH_ERRNO__ 1
// AARCH64-NEXT: #define __OBJC_BOOL_IS_BOOL 0
Expand Down
49 changes: 29 additions & 20 deletions clang/test/Preprocessor/init.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
// RUN: %clang_cc1 -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix INTERFERENCE %s
//
// We purposefully do not test the values produced, only that the macros are
// predefined to some value.
// INTERFERENCE:#define __GCC_CONSTRUCTIVE_SIZE {{.+}}
// INTERFERENCE:#define __GCC_DESTRUCTIVE_SIZE {{.+}}

// RUN: %clang_cc1 -E -dM -x assembler-with-cpp < /dev/null | FileCheck -match-full-lines -check-prefix ASM %s
//
// ASM:#define __ASSEMBLER__ 1
Expand Down Expand Up @@ -1697,6 +1704,8 @@
// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_SHORT_LOCK_FREE 2
// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
// WEBASSEMBLY-NEXT:#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
// WEBASSEMBLY-NEXT:#define __GCC_CONSTRUCTIVE_SIZE {{.+}}
// WEBASSEMBLY-NEXT:#define __GCC_DESTRUCTIVE_SIZE {{.+}}
// WEBASSEMBLY-NEXT:#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
// WEBASSEMBLY-NEXT:#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
// WEBASSEMBLY-NEXT:#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
Expand Down Expand Up @@ -1806,11 +1815,11 @@
// WEBASSEMBLY64-NEXT:#define __LONG_MAX__ 9223372036854775807L
// WEBASSEMBLY64-NEXT:#define __LONG_WIDTH__ 64
// 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 __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_MATH_ERRNO__ 1
// WEBASSEMBLY-NEXT:#define __OBJC_BOOL_IS_BOOL 0
Expand Down Expand Up @@ -2126,11 +2135,11 @@
// AVR:#define __LDBL_MIN__ 1.17549435e-38L
// AVR:#define __LONG_LONG_MAX__ 9223372036854775807LL
// 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 __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 __ORDER_BIG_ENDIAN__ 4321
// AVR:#define __ORDER_LITTLE_ENDIAN__ 1234
Expand Down Expand Up @@ -2422,11 +2431,11 @@
// RISCV32: #define __LITTLE_ENDIAN__ 1
// RISCV32: #define __LONG_LONG_MAX__ 9223372036854775807LL
// 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 __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 __POINTER_WIDTH__ 32
// RISCV32: #define __PRAGMA_REDEFINE_EXTNAME 1
Expand Down Expand Up @@ -2634,11 +2643,11 @@
// RISCV64: #define __LONG_LONG_MAX__ 9223372036854775807LL
// RISCV64: #define __LONG_MAX__ 9223372036854775807L
// 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 __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 __POINTER_WIDTH__ 64
// RISCV64: #define __PRAGMA_REDEFINE_EXTNAME 1
Expand Down
6 changes: 4 additions & 2 deletions clang/test/Preprocessor/predefined-win-macros.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// RUN: %clang_cc1 %s -x c++ -E -dM -triple x86_64-pc-win32 -fms-extensions -fms-compatibility \
// RUN: -fms-compatibility-version=19.00 -std=c++14 -o - | FileCheck -match-full-lines %s --check-prefix=CHECK-MS64
// RUN: %clang_cc1 %s -x c++ -E -dM -triple x86_64-pc-win32 -fms-extensions -fms-compatibility \
// RUN: -fms-compatibility-version=19.00 -std=c++14 -o - | grep GCC | count 5
// RUN: -fms-compatibility-version=19.00 -std=c++14 -o - | grep GCC | count 7
// CHECK-MS64: #define _INTEGRAL_MAX_BITS 64
// CHECK-MS64: #define _ISO_VOLATILE 1
// CHECK-MS64: #define _MSC_EXTENSIONS 1
Expand All @@ -26,7 +26,7 @@
// RUN: %clang_cc1 %s -x c++ -E -dM -triple i686-pc-win32 -fms-extensions -fms-compatibility \
// RUN: -fms-compatibility-version=19.00 -std=c++17 -o - | FileCheck -match-full-lines %s --check-prefix=CHECK-MS
// RUN: %clang_cc1 %s -x c++ -E -dM -triple i686-pc-win32 -fms-extensions -fms-compatibility \
// RUN: -fms-compatibility-version=19.00 -std=c++17 -o - | grep GCC | count 5
// RUN: -fms-compatibility-version=19.00 -std=c++17 -o - | grep GCC | count 7
// CHECK-MS: #define _INTEGRAL_MAX_BITS 64
// CHECK-MS: #define _ISO_VOLATILE 1
// CHECK-MS: #define _MSC_EXTENSIONS 1
Expand All @@ -39,6 +39,8 @@
// CHECK-MS-NOT: GNU
// CHECK-MS-NOT: GXX
// CHECK-MS: #define __GCC_ASM_FLAG_OUTPUTS__ 1
// CHECK-MS: #define __GCC_CONSTRUCTIVE_SIZE {{.+}}
// CHECK-MS: #define __GCC_DESTRUCTIVE_SIZE {{.+}}
// CHECK-MS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
// CHECK-MS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
// CHECK-MS: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
Expand Down
32 changes: 32 additions & 0 deletions clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5357,6 +5357,38 @@ TEST(TransferTest, ConditionalOperatorLocation) {
});
}

TEST(TransferTest, ConditionalOperatorOnConstantExpr) {
// This is a regression test: We used to crash when a `ConstantExpr` was used
// in the branches of a conditional operator.
std::string Code = R"cc(
consteval bool identity(bool B) { return B; }
void target(bool Cond) {
bool JoinTrueTrue = Cond ? identity(true) : identity(true);
bool JoinTrueFalse = Cond ? identity(true) : identity(false);
// [[p]]
}
)cc";
runDataflow(
Code,
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
ASTContext &ASTCtx) {
Environment Env = getEnvironmentAtAnnotation(Results, "p").fork();

auto &JoinTrueTrue =
getValueForDecl<BoolValue>(ASTCtx, Env, "JoinTrueTrue");
// FIXME: This test documents the current behavior, namely that we
// don't actually use the constant result of the `ConstantExpr` and
// instead treat it like a normal function call.
EXPECT_EQ(JoinTrueTrue.formula().kind(), Formula::Kind::AtomRef);
// EXPECT_TRUE(JoinTrueTrue.formula().literal());

auto &JoinTrueFalse =
getValueForDecl<BoolValue>(ASTCtx, Env, "JoinTrueFalse");
EXPECT_EQ(JoinTrueFalse.formula().kind(), Formula::Kind::AtomRef);
},
LangStandard::lang_cxx20);
}

TEST(TransferTest, IfStmtBranchExtendsFlowCondition) {
std::string Code = R"(
void target(bool Foo) {
Expand Down
25 changes: 17 additions & 8 deletions clang/unittests/Format/FormatTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24507,16 +24507,25 @@ TEST_F(FormatTest, AlternativeOperators) {
verifyFormat("int a compl(5);");
verifyFormat("int a not(5);");

/* FIXME handle alternate tokens
* https://en.cppreference.com/w/cpp/language/operator_alternative
// alternative tokens
verifyFormat("compl foo();"); // ~foo();
verifyFormat("foo() <%%>;"); // foo();
verifyFormat("void foo() <%%>;"); // void foo(){}
verifyFormat("int a <:1:>;"); // int a[1];[
verifyFormat("compl foo();"); // ~foo();
verifyFormat("foo() <%%>"); // foo() {}
verifyFormat("void foo() <%%>"); // void foo() {}
verifyFormat("int a<:1:>;"); // int a[1];
verifyFormat("%:define ABC abc"); // #define ABC abc
verifyFormat("%:%:"); // ##
*/

verifyFormat("a = v(not;);\n"
"b = v(not+);\n"
"c = v(not x);\n"
"d = v(not 1);\n"
"e = v(not 123.f);");

verifyNoChange("#define ASSEMBLER_INSTRUCTION_LIST(V) \\\n"
" V(and) \\\n"
" V(not) \\\n"
" V(not!) \\\n"
" V(other)",
getLLVMStyleWithColumns(40));
}

TEST_F(FormatTest, STLWhileNotDefineChed) {
Expand Down
2 changes: 1 addition & 1 deletion clang/www/cxx_dr_status.html
Original file line number Diff line number Diff line change
Expand Up @@ -12702,7 +12702,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2>
<td><a href="https://cplusplus.github.io/CWG/issues/2149.html">2149</a></td>
<td>drafting</td>
<td>Brace elision and array length deduction</td>
<td align="center">Not resolved</td>
<td title="Clang 3.1 implements 2024-04 resolution" align="center">Not Resolved*</td>
</tr>
<tr id="2150">
<td><a href="https://cplusplus.github.io/CWG/issues/2150.html">2150</a></td>
Expand Down
10 changes: 4 additions & 6 deletions compiler-rt/lib/scudo/standalone/wrappers_c.inc
Original file line number Diff line number Diff line change
Expand Up @@ -252,13 +252,11 @@ INTERFACE WEAK int SCUDO_PREFIX(mallopt)(int param, int value) {
// introduced by interval transition.
SCUDO_ALLOCATOR.releaseToOS(scudo::ReleaseToOS::Force);

if (value == 0) {
// Will set the release values to their minimum values.
value = INT32_MIN;
} else {
// Will set the release values to their maximum values.
// The values allowed on Android are {-1, 0, 1}. "1" means the longest
// interval.
CHECK(value >= -1 && value <= 1);
if (value == 1)
value = INT32_MAX;
}
}

SCUDO_ALLOCATOR.setOption(scudo::Option::ReleaseInterval,
Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/test/asan/TestCases/Darwin/odr-lto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

// RUN: %clangxx_asan -DPART=0 -c %s -o %t-1.o -flto -mllvm -asan-use-private-alias
// RUN: %clangxx_asan -DPART=1 -c %s -o %t-2.o -flto -mllvm -asan-use-private-alias
// RUN: %clangxx_asan_lto %t-1.o %t-2.o -o %t -flto -mlinker-version=133
// RUN: %clangxx_asan_lto %t-1.o %t-2.o -o %t -flto
// RUN: %run %t 2>&1 | FileCheck %s

#include <stdio.h>
Expand Down
7 changes: 2 additions & 5 deletions flang/include/flang/Optimizer/Transforms/Passes.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ namespace fir {
#define GEN_PASS_DECL_POLYMORPHICOPCONVERSION
#define GEN_PASS_DECL_OPENACCDATAOPERANDCONVERSION
#define GEN_PASS_DECL_ADDDEBUGINFO
#define GEN_PASS_DECL_STACKARRAYS
#define GEN_PASS_DECL_LOOPVERSIONING
#include "flang/Optimizer/Transforms/Passes.h.inc"

std::unique_ptr<mlir::Pass> createAffineDemotionPass();
Expand All @@ -57,15 +59,10 @@ std::unique_ptr<mlir::Pass>
createExternalNameConversionPass(bool appendUnderscore);
std::unique_ptr<mlir::Pass> createMemDataFlowOptPass();
std::unique_ptr<mlir::Pass> createPromoteToAffinePass();
std::unique_ptr<mlir::Pass> createMemoryAllocationPass();
std::unique_ptr<mlir::Pass> createStackArraysPass();
std::unique_ptr<mlir::Pass> createAliasTagsPass();
std::unique_ptr<mlir::Pass>
createAddDebugInfoPass(fir::AddDebugInfoOptions options = {});
std::unique_ptr<mlir::Pass> createLoopVersioningPass();

std::unique_ptr<mlir::Pass>
createMemoryAllocationPass(bool dynOnHeap, std::size_t maxStackSize);
std::unique_ptr<mlir::Pass> createAnnotateConstantOperandsPass();
std::unique_ptr<mlir::Pass> createAlgebraicSimplificationPass();
std::unique_ptr<mlir::Pass>
Expand Down
3 changes: 0 additions & 3 deletions flang/include/flang/Optimizer/Transforms/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,6 @@ def MemoryAllocationOpt : Pass<"memory-allocation-opt", "mlir::func::FuncOp"> {
"std::size_t", /*default=*/"~static_cast<std::size_t>(0)",
"Set maximum number of elements of an array allocated on the stack.">
];
let constructor = "::fir::createMemoryAllocationPass()";
}

def StackArrays : Pass<"stack-arrays", "mlir::ModuleOp"> {
Expand All @@ -257,7 +256,6 @@ def StackArrays : Pass<"stack-arrays", "mlir::ModuleOp"> {
allocations.
}];
let dependentDialects = [ "fir::FIROpsDialect" ];
let constructor = "::fir::createStackArraysPass()";
}

def AddAliasTags : Pass<"fir-add-alias-tags", "mlir::ModuleOp"> {
Expand Down Expand Up @@ -321,7 +319,6 @@ def LoopVersioning : Pass<"loop-versioning", "mlir::func::FuncOp"> {
an array has element sized stride. The element sizes stride allows some
loops to be vectorized as well as other loop optimizations.
}];
let constructor = "::fir::createLoopVersioningPass()";
let dependentDialects = [ "fir::FIROpsDialect" ];
}

Expand Down
1 change: 1 addition & 0 deletions flang/include/flang/Runtime/descriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,7 @@ class alignas(Descriptor) StaticDescriptor {
assert(descriptor().rank() <= maxRank);
assert(descriptor().SizeInBytes() <= byteSize);
if (DescriptorAddendum * addendum{descriptor().Addendum()}) {
(void)addendum;
assert(hasAddendum);
assert(addendum->LenParameters() <= maxLengthTypeParameters);
} else {
Expand Down
8 changes: 4 additions & 4 deletions flang/include/flang/Tools/CLOptions.inc
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,8 @@ inline void addAVC(

inline void addMemoryAllocationOpt(mlir::PassManager &pm) {
addNestedPassConditionally<mlir::func::FuncOp>(pm, disableFirMao, [&]() {
return fir::createMemoryAllocationPass(
dynamicArrayStackToHeapAllocation, arrayStackAllocationThreshold);
return fir::createMemoryAllocationOpt(
{dynamicArrayStackToHeapAllocation, arrayStackAllocationThreshold});
});
}

Expand Down Expand Up @@ -253,12 +253,12 @@ inline void createDefaultFIROptimizerPassPipeline(
}

if (pc.LoopVersioning)
pm.addPass(fir::createLoopVersioningPass());
pm.addPass(fir::createLoopVersioning());

pm.addPass(mlir::createCSEPass());

if (pc.StackArrays)
pm.addPass(fir::createStackArraysPass());
pm.addPass(fir::createStackArrays());
else
fir::addMemoryAllocationOpt(pm);

Expand Down
28 changes: 23 additions & 5 deletions flang/lib/Lower/Bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3806,16 +3806,34 @@ class FirConverter : public Fortran::lower::AbstractConverter {
return temps;
}

// Check if the insertion point is currently in a device context. HostDevice
// subprogram are not considered fully device context so it will return false
// for it.
static bool isDeviceContext(fir::FirOpBuilder &builder) {
if (builder.getRegion().getParentOfType<fir::CUDAKernelOp>())
return true;
if (auto funcOp =
builder.getRegion().getParentOfType<mlir::func::FuncOp>()) {
if (auto cudaProcAttr =
funcOp.getOperation()->getAttrOfType<fir::CUDAProcAttributeAttr>(
fir::getCUDAAttrName())) {
return cudaProcAttr.getValue() != fir::CUDAProcAttribute::Host &&
cudaProcAttr.getValue() != fir::CUDAProcAttribute::HostDevice;
}
}
return false;
}

void genDataAssignment(
const Fortran::evaluate::Assignment &assign,
const Fortran::evaluate::ProcedureRef *userDefinedAssignment) {
mlir::Location loc = getCurrentLocation();
fir::FirOpBuilder &builder = getFirOpBuilder();

bool isInDeviceContext =
builder.getRegion().getParentOfType<fir::CUDAKernelOp>();
bool isCUDATransfer = Fortran::evaluate::HasCUDAAttrs(assign.lhs) ||
Fortran::evaluate::HasCUDAAttrs(assign.rhs);
bool isInDeviceContext = isDeviceContext(builder);
bool isCUDATransfer = (Fortran::evaluate::HasCUDAAttrs(assign.lhs) ||
Fortran::evaluate::HasCUDAAttrs(assign.rhs)) &&
!isInDeviceContext;
bool hasCUDAImplicitTransfer =
Fortran::evaluate::HasCUDAImplicitTransfer(assign.rhs);
llvm::SmallVector<mlir::Value> implicitTemps;
Expand Down Expand Up @@ -3878,7 +3896,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
Fortran::lower::StatementContext localStmtCtx;
hlfir::Entity rhs = evaluateRhs(localStmtCtx);
hlfir::Entity lhs = evaluateLhs(localStmtCtx);
if (isCUDATransfer && !hasCUDAImplicitTransfer && !isInDeviceContext)
if (isCUDATransfer && !hasCUDAImplicitTransfer)
genCUDADataTransfer(builder, loc, assign, lhs, rhs);
else
builder.create<hlfir::AssignOp>(loc, rhs, lhs,
Expand Down
1 change: 1 addition & 0 deletions flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ void DataSharingProcessor::defaultPrivatize(
if (!Fortran::semantics::IsProcedure(*sym) &&
!sym->GetUltimate().has<Fortran::semantics::DerivedTypeDetails>() &&
!sym->GetUltimate().has<Fortran::semantics::NamelistDetails>() &&
!Fortran::semantics::IsImpliedDoIndex(sym->GetUltimate()) &&
!symbolsInNestedRegions.contains(sym) &&
!symbolsInParentRegions.contains(sym) &&
!privatizedSymbols.contains(sym))
Expand Down
4 changes: 0 additions & 4 deletions flang/lib/Optimizer/Transforms/LoopVersioning.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,3 @@ void LoopVersioningPass::runOnOperation() {

LLVM_DEBUG(llvm::dbgs() << "=== End " DEBUG_TYPE " ===\n");
}

std::unique_ptr<mlir::Pass> fir::createLoopVersioningPass() {
return std::make_unique<LoopVersioningPass>();
}
30 changes: 7 additions & 23 deletions flang/lib/Optimizer/Transforms/MemoryAllocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,6 @@ namespace fir {
static constexpr std::size_t unlimitedArraySize = ~static_cast<std::size_t>(0);

namespace {
struct MemoryAllocationOptions {
// Always move dynamic array allocations to the heap. This may result in more
// heap fragmentation, so may impact performance negatively.
bool dynamicArrayOnHeap = false;

// Number of elements in array threshold for moving to heap. In environments
// with limited stack size, moving large arrays to the heap can avoid running
// out of stack space.
std::size_t maxStackArraySize = unlimitedArraySize;
};

class ReturnAnalysis {
public:
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(ReturnAnalysis)
Expand Down Expand Up @@ -68,8 +57,9 @@ class ReturnAnalysis {

/// Return `true` if this allocation is to remain on the stack (`fir.alloca`).
/// Otherwise the allocation should be moved to the heap (`fir.allocmem`).
static inline bool keepStackAllocation(fir::AllocaOp alloca, mlir::Block *entry,
const MemoryAllocationOptions &options) {
static inline bool
keepStackAllocation(fir::AllocaOp alloca, mlir::Block *entry,
const fir::MemoryAllocationOptOptions &options) {
// Limitation: only arrays allocated on the stack in the entry block are
// considered for now.
// TODO: Generalize the algorithm and placement of the freemem nodes.
Expand Down Expand Up @@ -168,6 +158,9 @@ class MemoryAllocationOpt
options = {dynOnHeap, maxStackSize};
}

MemoryAllocationOpt(const fir::MemoryAllocationOptOptions &options)
: options{options} {}

/// Override `options` if command-line options have been set.
inline void useCommandLineOptions() {
if (dynamicArrayOnHeap)
Expand Down Expand Up @@ -211,15 +204,6 @@ class MemoryAllocationOpt
}

private:
MemoryAllocationOptions options;
fir::MemoryAllocationOptOptions options;
};
} // namespace

std::unique_ptr<mlir::Pass> fir::createMemoryAllocationPass() {
return std::make_unique<MemoryAllocationOpt>();
}

std::unique_ptr<mlir::Pass>
fir::createMemoryAllocationPass(bool dynOnHeap, std::size_t maxStackSize) {
return std::make_unique<MemoryAllocationOpt>(dynOnHeap, maxStackSize);
}
4 changes: 0 additions & 4 deletions flang/lib/Optimizer/Transforms/StackArrays.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,3 @@ void StackArraysPass::runOnFunc(mlir::Operation *func) {
signalPassFailure();
}
}

std::unique_ptr<mlir::Pass> fir::createStackArraysPass() {
return std::make_unique<StackArraysPass>();
}
Loading