33 changes: 33 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ Removed Compiler Flags
Attribute Changes in Clang
--------------------------

- Clang now disallows more than one ``__attribute__((ownership_returns(class, idx)))`` with
different class names attached to one function.

Improvements to Clang's diagnostics
-----------------------------------

Expand All @@ -121,6 +124,10 @@ Improvements to Clang's diagnostics
template <typename> int i; // error: non-static data member 'i' cannot be declared as a template
};

- Clang now diagnoses dangling references to fields of temporary objects. Fixes #GH81589.

- Clang now diagnoses undefined behavior in constant expressions more consistently. This includes invalid shifts, and signed overflow in arithmetic.

Improvements to Clang's time-trace
----------------------------------

Expand All @@ -130,6 +137,9 @@ Improvements to Coverage Mapping
Bug Fixes in This Version
-------------------------

- Fixed the definition of ``ATOMIC_FLAG_INIT`` in ``<stdatomic.h>`` so it can
be used in C++.

Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand All @@ -139,6 +149,8 @@ Bug Fixes to Attribute Support
Bug Fixes to C++ Support
^^^^^^^^^^^^^^^^^^^^^^^^

- Fixed a crash when an expression with a dependent ``__typeof__`` type is used as the operand of a unary operator. (#GH97646)

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^

Expand All @@ -160,6 +172,22 @@ AMDGPU Support
X86 Support
^^^^^^^^^^^

- The MMX vector intrinsic functions from ``*mmintrin.h`` which
operate on `__m64` vectors, such as ``_mm_add_pi8``, have been
reimplemented to use the SSE2 instruction-set and XMM registers
unconditionally. These intrinsics are therefore *no longer
supported* if MMX is enabled without SSE2 -- either from targeting
CPUs from the Pentium-MMX through the Pentium 3, or explicitly via
passing arguments such as ``-mmmx -mno-sse2``. MMX assembly code
remains supported without requiring SSE2, including inside
inline-assembly.

- The compiler builtins such as ``__builtin_ia32_paddb`` which
formerly implemented the above MMX intrinsic functions have been
removed. Any uses of these removed functions should migrate to the
functions defined by the ``*mmintrin.h`` headers. A mapping can be
found in the file ``clang/www/builtins.py``.

Arm and AArch64 Support
^^^^^^^^^^^^^^^^^^^^^^^

Expand Down Expand Up @@ -217,6 +245,11 @@ Static Analyzer
New features
^^^^^^^^^^^^

- MallocChecker now checks for ``ownership_returns(class, idx)`` and ``ownership_takes(class, idx)``
attributes with class names different from "malloc". Clang static analyzer now reports an error
if class of allocation and deallocation function mismatches.
`Documentation <https://clang.llvm.org/docs/analyzer/checkers.html#unix-mismatcheddeallocator-c-c>`__.

Crash and bug fixes
^^^^^^^^^^^^^^^^^^^

Expand Down
10 changes: 10 additions & 0 deletions clang/docs/analyzer/checkers/mismatched_deallocator_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ void test() {

// C, C++
void __attribute((ownership_returns(malloc))) *user_malloc(size_t);
void __attribute((ownership_takes(malloc, 1))) *user_free(void *);

void __attribute((ownership_returns(malloc1))) *user_malloc1(size_t);
void __attribute((ownership_takes(malloc1, 1))) *user_free1(void *);

void test() {
int *p = (int *)user_malloc(sizeof(int));
Expand All @@ -24,6 +28,12 @@ void test() {
realloc(p, sizeof(long)); // warn
}

// C, C++
void test() {
int *p = user_malloc(10);
user_free1(p); // warn
}

// C, C++
template <typename T>
struct SimpleSmartPointer {
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -8434,7 +8434,7 @@ inline bool Type::isUndeducedType() const {
/// Determines whether this is a type for which one can define
/// an overloaded operator.
inline bool Type::isOverloadableType() const {
if (!CanonicalType->isDependentType())
if (!isDependentType())
return isRecordType() || isEnumeralType();
return !isArrayType() && !isFunctionType() && !isAnyPointerType() &&
!isMemberPointerType();
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/BuiltinsWebAssembly.def
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ TARGET_BUILTIN(__builtin_wasm_loadf16_f32, "fh*", "nU", "half-precision")
TARGET_BUILTIN(__builtin_wasm_storef16_f32, "vfh*", "n", "half-precision")
TARGET_BUILTIN(__builtin_wasm_splat_f16x8, "V8hf", "nc", "half-precision")
TARGET_BUILTIN(__builtin_wasm_extract_lane_f16x8, "fV8hi", "nc", "half-precision")
TARGET_BUILTIN(__builtin_wasm_replace_lane_f16x8, "V8hV8hif", "nc", "half-precision")

// Reference Types builtins
// Some builtins are custom type-checked - see 't' as part of the third argument,
Expand Down
103 changes: 2 additions & 101 deletions clang/include/clang/Basic/BuiltinsX86.def
Original file line number Diff line number Diff line change
Expand Up @@ -47,107 +47,8 @@ TARGET_BUILTIN(__builtin_ia32_writeeflags_u32, "vUi", "n", "")
// doesn't work in the presence of re-declaration of _mm_prefetch for windows.
TARGET_BUILTIN(_mm_prefetch, "vcC*i", "nc", "mmx")
TARGET_BUILTIN(__builtin_ia32_emms, "v", "n", "mmx")
TARGET_BUILTIN(__builtin_ia32_paddb, "V8cV8cV8c", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_paddw, "V4sV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_paddd, "V2iV2iV2i", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_paddsb, "V8cV8cV8c", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_paddsw, "V4sV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_paddusb, "V8cV8cV8c", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_paddusw, "V4sV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psubb, "V8cV8cV8c", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psubw, "V4sV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psubd, "V2iV2iV2i", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psubsb, "V8cV8cV8c", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psubsw, "V4sV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psubusb, "V8cV8cV8c", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psubusw, "V4sV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pmulhw, "V4sV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pmullw, "V4sV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pmaddwd, "V2iV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pand, "V1OiV1OiV1Oi", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pandn, "V1OiV1OiV1Oi", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_por, "V1OiV1OiV1Oi", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pxor, "V1OiV1OiV1Oi", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psllw, "V4sV4sV1Oi", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pslld, "V2iV2iV1Oi", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psllq, "V1OiV1OiV1Oi", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psrlw, "V4sV4sV1Oi", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psrld, "V2iV2iV1Oi", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psrlq, "V1OiV1OiV1Oi", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psraw, "V4sV4sV1Oi", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psrad, "V2iV2iV1Oi", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psllwi, "V4sV4si", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pslldi, "V2iV2ii", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psllqi, "V1OiV1Oii", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psrlwi, "V4sV4si", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psrldi, "V2iV2ii", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psrlqi, "V1OiV1Oii", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psrawi, "V4sV4si", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_psradi, "V2iV2ii", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_packsswb, "V8cV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_packssdw, "V4sV2iV2i", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_packuswb, "V8cV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_punpckhbw, "V8cV8cV8c", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_punpckhwd, "V4sV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_punpckhdq, "V2iV2iV2i", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_punpcklbw, "V8cV8cV8c", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_punpcklwd, "V4sV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_punpckldq, "V2iV2iV2i", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pcmpeqb, "V8cV8cV8c", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pcmpeqw, "V4sV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pcmpeqd, "V2iV2iV2i", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pcmpgtb, "V8cV8cV8c", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pcmpgtw, "V4sV4sV4s", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_pcmpgtd, "V2iV2iV2i", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_maskmovq, "vV8cV8cc*", "nV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_movntq, "vV1Oi*V1Oi", "nV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_vec_init_v2si, "V2iii", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_vec_init_v4hi, "V4sssss", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_vec_init_v8qi, "V8ccccccccc", "ncV:64:", "mmx")
TARGET_BUILTIN(__builtin_ia32_vec_ext_v2si, "iV2ii", "ncV:64:", "mmx")

// MMX2 (MMX+SSE) intrinsics
TARGET_BUILTIN(__builtin_ia32_cvtpi2ps, "V4fV4fV2i", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_cvtps2pi, "V2iV4f", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_cvttps2pi, "V2iV4f", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_pavgb, "V8cV8cV8c", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_pavgw, "V4sV4sV4s", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_pmaxsw, "V4sV4sV4s", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_pmaxub, "V8cV8cV8c", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_pminsw, "V4sV4sV4s", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_pminub, "V8cV8cV8c", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_pmovmskb, "iV8c", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_pmulhuw, "V4sV4sV4s", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_psadbw, "V4sV8cV8c", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_pshufw, "V4sV4sIc", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_vec_ext_v4hi, "iV4sIi", "ncV:64:", "mmx,sse")
TARGET_BUILTIN(__builtin_ia32_vec_set_v4hi, "V4sV4siIi", "ncV:64:", "mmx,sse")

// MMX+SSE2
TARGET_BUILTIN(__builtin_ia32_cvtpd2pi, "V2iV2d", "ncV:64:", "mmx,sse2")
TARGET_BUILTIN(__builtin_ia32_cvtpi2pd, "V2dV2i", "ncV:64:", "mmx,sse2")
TARGET_BUILTIN(__builtin_ia32_cvttpd2pi, "V2iV2d", "ncV:64:", "mmx,sse2")
TARGET_BUILTIN(__builtin_ia32_paddq, "V1OiV1OiV1Oi", "ncV:64:", "mmx,sse2")
TARGET_BUILTIN(__builtin_ia32_pmuludq, "V1OiV2iV2i", "ncV:64:", "mmx,sse2")
TARGET_BUILTIN(__builtin_ia32_psubq, "V1OiV1OiV1Oi", "ncV:64:", "mmx,sse2")

// MMX+SSSE3
TARGET_BUILTIN(__builtin_ia32_pabsb, "V8cV8c", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_pabsd, "V2iV2i", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_pabsw, "V4sV4s", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_palignr, "V8cV8cV8cIc", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_phaddd, "V2iV2iV2i", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_phaddsw, "V4sV4sV4s", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_phaddw, "V4sV4sV4s", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_phsubd, "V2iV2iV2i", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_phsubsw, "V4sV4sV4s", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_phsubw, "V4sV4sV4s", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_pmaddubsw, "V8cV8cV8c", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_pmulhrsw, "V4sV4sV4s", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_pshufb, "V8cV8cV8c", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_psignw, "V4sV4sV4s", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_psignb, "V8cV8cV8c", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_psignd, "V2iV2iV2i", "ncV:64:", "mmx,ssse3")
TARGET_BUILTIN(__builtin_ia32_vec_ext_v4hi, "sV4sIi", "ncV:64:", "sse")
TARGET_BUILTIN(__builtin_ia32_vec_set_v4hi, "V4sV4ssIi", "ncV:64:", "sse")

// SSE intrinsics.
TARGET_BUILTIN(__builtin_ia32_comieq, "iV4fV4f", "ncV:128:", "sse")
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/CodeGenOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,9 @@ CODEGENOPT(ForceAAPCSBitfieldLoad, 1, 0)
/// Assume that by-value parameters do not alias any other values.
CODEGENOPT(PassByValueIsNoAlias, 1, 0)

/// Whether to store register parameters to stack.
CODEGENOPT(SaveRegParams, 1, 0)

/// Whether to not follow the AAPCS that enforces volatile bit-field access width to be
/// according to the field declaring type width.
CODEGENOPT(AAPCSBitfieldWidth, 1, 1)
Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -942,6 +942,9 @@ def warn_ptrauth_auth_null_pointer :
InGroup<PtrAuthNullPointers>;
def err_ptrauth_string_not_literal : Error<
"argument must be a string literal%select{| of char type}0">;
def err_ptrauth_type_disc_undiscriminated : Error<
"cannot pass undiscriminated type %0 to "
"'__builtin_ptrauth_type_discriminator'">;

def note_ptrauth_virtual_function_pointer_incomplete_arg_ret :
Note<"cannot take an address of a virtual member function if its return or "
Expand Down Expand Up @@ -3331,6 +3334,10 @@ def err_ownership_returns_index_mismatch : Error<
"'ownership_returns' attribute index does not match; here it is %0">;
def note_ownership_returns_index_mismatch : Note<
"declared with index %0 here">;
def err_ownership_takes_class_mismatch : Error<
"'ownership_takes' attribute class does not match; here it is '%0'">;
def note_ownership_takes_class_mismatch : Note<
"declared with class '%0' here">;
def err_format_strftime_third_parameter : Error<
"strftime format attribute requires 3rd parameter to be 0">;
def err_format_attribute_not : Error<"format argument not a string type">;
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/TokenKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,8 @@ ALIAS("__is_same_as", __is_same, KEYCXX)
KEYWORD(__private_extern__ , KEYALL)
KEYWORD(__module_private__ , KEYALL)

UNARY_EXPR_OR_TYPE_TRAIT(__builtin_ptrauth_type_discriminator, PtrAuthTypeDiscriminator, KEYALL)

// Extension that will be enabled for Microsoft, Borland and PS4, but can be
// disabled via '-fno-declspec'.
KEYWORD(__declspec , 0)
Expand Down
15 changes: 10 additions & 5 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1165,19 +1165,19 @@ def client__name : JoinedOrSeparate<["-"], "client_name">;
def combine : Flag<["-", "--"], "combine">, Flags<[NoXarchOption, Unsupported]>;
def compatibility__version : JoinedOrSeparate<["-"], "compatibility_version">;
def config : Joined<["--"], "config=">, Flags<[NoXarchOption]>,
Visibility<[ClangOption, CLOption, DXCOption]>, MetaVarName<"<file>">,
Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, MetaVarName<"<file>">,
HelpText<"Specify configuration file">;
def : Separate<["--"], "config">, Alias<config>;
def : Separate<["--"], "config">, Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, Alias<config>;
def no_default_config : Flag<["--"], "no-default-config">,
Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption, DXCOption]>,
Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>,
HelpText<"Disable loading default configuration files">;
def config_system_dir_EQ : Joined<["--"], "config-system-dir=">,
Flags<[NoXarchOption, HelpHidden]>,
Visibility<[ClangOption, CLOption, DXCOption]>,
Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>,
HelpText<"System directory for configuration files">;
def config_user_dir_EQ : Joined<["--"], "config-user-dir=">,
Flags<[NoXarchOption, HelpHidden]>,
Visibility<[ClangOption, CLOption, DXCOption]>,
Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>,
HelpText<"User directory for configuration files">;
def coverage : Flag<["-", "--"], "coverage">, Group<Link_Group>,
Visibility<[ClangOption, CLOption]>;
Expand Down Expand Up @@ -5089,6 +5089,11 @@ def mspe : Flag<["-"], "mspe">, Group<m_ppc_Features_Group>;
def mno_spe : Flag<["-"], "mno-spe">, Group<m_ppc_Features_Group>;
def mefpu2 : Flag<["-"], "mefpu2">, Group<m_ppc_Features_Group>;
} // let Flags = [TargetSpecific]
def msave_reg_params : Flag<["-"], "msave-reg-params">, Group<m_Group>,
Flags<[TargetSpecific]>,
Visibility<[ClangOption, CC1Option]>,
HelpText<"Save arguments passed by registers to ABI-defined stack positions">,
MarshallingInfoFlag<CodeGenOpts<"SaveRegParams">>;
def mabi_EQ_quadword_atomics : Flag<["-"], "mabi=quadword-atomics">,
Group<m_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Enable quadword atomics ABI on AIX (AIX PPC64 only). Uses lqarx/stqcx. instructions.">,
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -3890,6 +3890,8 @@ class Parser : public CodeCompletionHandler {
ExprResult ParseArrayTypeTrait();
ExprResult ParseExpressionTrait();

ExprResult ParseBuiltinPtrauthTypeDiscriminator();

//===--------------------------------------------------------------------===//
// Preprocessor code-completion pass-through
void CodeCompleteDirective(bool InConditional) override;
Expand Down
4 changes: 3 additions & 1 deletion clang/include/clang/Sema/Overload.h
Original file line number Diff line number Diff line change
Expand Up @@ -998,7 +998,9 @@ class Sema;
private:
friend class OverloadCandidateSet;
OverloadCandidate()
: IsSurrogate(false), IsADLCandidate(CallExpr::NotADL), RewriteKind(CRK_None) {}
: IsSurrogate(false), IgnoreObjectArgument(false),
TookAddressOfOverload(false), IsADLCandidate(CallExpr::NotADL),
RewriteKind(CRK_None) {}
};

/// OverloadCandidateSet - A set of overload candidates, used in C++
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -3456,6 +3456,8 @@ class Sema final : public SemaBase {
TemplateIdAnnotation *TemplateId,
bool IsMemberSpecialization);

bool checkPointerAuthEnabled(SourceLocation Loc, SourceRange Range);

bool checkConstantPointerAuthKey(Expr *keyExpr, unsigned &key);

/// Diagnose function specifiers on a declaration of an identifier that
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3363,6 +3363,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
#include "clang/Basic/RISCVVTypes.def"
llvm_unreachable("not yet implemented");
}
llvm_unreachable("should never get here");
}
case Type::Record: {
const RecordDecl *RD = T->getAs<RecordType>()->getDecl();
Expand Down
32 changes: 23 additions & 9 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2843,6 +2843,8 @@ static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E,
// During constant-folding, a negative shift is an opposite shift. Such
// a shift is not a constant expression.
Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
if (!Info.noteUndefinedBehavior())
return false;
RHS = -RHS;
goto shift_right;
}
Expand All @@ -2853,19 +2855,23 @@ static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E,
if (SA != RHS) {
Info.CCEDiag(E, diag::note_constexpr_large_shift)
<< RHS << E->getType() << LHS.getBitWidth();
if (!Info.noteUndefinedBehavior())
return false;
} else if (LHS.isSigned() && !Info.getLangOpts().CPlusPlus20) {
// C++11 [expr.shift]p2: A signed left shift must have a non-negative
// operand, and must not overflow the corresponding unsigned type.
// C++2a [expr.shift]p2: E1 << E2 is the unique value congruent to
// E1 x 2^E2 module 2^N.
if (LHS.isNegative())
if (LHS.isNegative()) {
Info.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
else if (LHS.countl_zero() < SA)
if (!Info.noteUndefinedBehavior())
return false;
} else if (LHS.countl_zero() < SA) {
Info.CCEDiag(E, diag::note_constexpr_lshift_discards);
if (!Info.noteUndefinedBehavior())
return false;
}
}
if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
Info.getLangOpts().CPlusPlus11)
return false;
Result = LHS << SA;
return true;
}
Expand All @@ -2879,20 +2885,22 @@ static bool handleIntIntBinOp(EvalInfo &Info, const BinaryOperator *E,
// During constant-folding, a negative shift is an opposite shift. Such a
// shift is not a constant expression.
Info.CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
if (!Info.noteUndefinedBehavior())
return false;
RHS = -RHS;
goto shift_left;
}
shift_right:
// C++11 [expr.shift]p1: Shift width must be less than the bit width of the
// shifted type.
unsigned SA = (unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
if (SA != RHS)
if (SA != RHS) {
Info.CCEDiag(E, diag::note_constexpr_large_shift)
<< RHS << E->getType() << LHS.getBitWidth();
if (!Info.noteUndefinedBehavior())
return false;
}

if (Info.EvalStatus.Diag && !Info.EvalStatus.Diag->empty() &&
Info.getLangOpts().CPlusPlus11)
return false;
Result = LHS >> SA;
return true;
}
Expand Down Expand Up @@ -14058,6 +14066,12 @@ bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
E);
}

case UETT_PtrAuthTypeDiscriminator: {
if (E->getArgumentType()->isDependentType())
return false;
return Success(
Info.Ctx.getPointerAuthTypeDiscriminator(E->getArgumentType()), E);
}
case UETT_VecStep: {
QualType Ty = E->getTypeOfArgument();

Expand Down
12 changes: 10 additions & 2 deletions clang/lib/AST/Interp/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ bool InitLink::emit(Compiler<Emitter> *Ctx, const Expr *E) const {
return Ctx->emitGetPtrLocal(Offset, E);
case K_Decl:
return Ctx->visitDeclRef(D, E);
case K_Elem:
if (!Ctx->emitConstUint32(Offset, E))
return false;
return Ctx->emitArrayElemPtrUint32(E);
default:
llvm_unreachable("Unhandled InitLink kind");
}
Expand Down Expand Up @@ -1556,6 +1560,7 @@ bool Compiler<Emitter>::visitArrayElemInit(unsigned ElemIndex,
return this->emitInitElem(*T, ElemIndex, Init);
}

InitLinkScope<Emitter> ILS(this, InitLink::Elem(ElemIndex));
// Advance the pointer currently on the stack to the given
// dimension.
if (!this->emitConstUint32(ElemIndex, Init))
Expand Down Expand Up @@ -3683,6 +3688,9 @@ VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD, bool Topleve
const Expr *Init = VD->getInit();
std::optional<PrimType> VarT = classify(VD->getType());

if (Init && Init->isValueDependent())
return false;

if (Context::shouldBeGloballyIndexed(VD)) {
auto checkDecl = [&]() -> bool {
bool NeedsOp = !Toplevel && VD->isLocalVarDecl() && VD->isStaticLocal();
Expand Down Expand Up @@ -5278,8 +5286,8 @@ template <class Emitter>
unsigned Compiler<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();
if (const auto *R = Ty->getPointeeCXXRecordDecl())
return R;
return Ty->getAsCXXRecordDecl();
};
const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType);
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/AST/Interp/Compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ struct InitLink {
K_Field = 1,
K_Temp = 2,
K_Decl = 3,
K_Elem = 5,
};

static InitLink This() { return InitLink{K_This}; }
Expand All @@ -68,6 +69,11 @@ struct InitLink {
IL.D = D;
return IL;
}
static InitLink Elem(unsigned Index) {
InitLink IL{K_Elem};
IL.Offset = Index;
return IL;
}

InitLink(uint8_t Kind) : Kind(Kind) {}
template <class Emitter>
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/AST/Interp/Interp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,8 @@ void cleanupAfterFunctionCall(InterpState &S, CodePtr OpPC) {
assert(false && "Can't get arguments from that expression type");

assert(NumArgs >= CurFunc->getNumWrittenParams());
NumVarArgs = NumArgs - CurFunc->getNumWrittenParams();
NumVarArgs = NumArgs - (CurFunc->getNumWrittenParams() +
isa<CXXOperatorCallExpr>(CallSite));
for (unsigned I = 0; I != NumVarArgs; ++I) {
const Expr *A = Args[NumArgs - 1 - I];
popArg(S, A);
Expand Down
22 changes: 14 additions & 8 deletions clang/lib/AST/Interp/Interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@ bool CheckShift(InterpState &S, CodePtr OpPC, const LT &LHS, const RT &RHS,
if (RHS.isNegative()) {
const SourceInfo &Loc = S.Current->getSource(OpPC);
S.CCEDiag(Loc, diag::note_constexpr_negative_shift) << RHS.toAPSInt();
return false;
if (!S.noteUndefinedBehavior())
return false;
}

// C++11 [expr.shift]p1: Shift width must be less than the bit width of
Expand All @@ -163,17 +164,24 @@ bool CheckShift(InterpState &S, CodePtr OpPC, const LT &LHS, const RT &RHS,
const APSInt Val = RHS.toAPSInt();
QualType Ty = E->getType();
S.CCEDiag(E, diag::note_constexpr_large_shift) << Val << Ty << Bits;
return !(S.getEvalStatus().Diag && !S.getEvalStatus().Diag->empty() && S.getLangOpts().CPlusPlus11);
if (!S.noteUndefinedBehavior())
return false;
}

if (LHS.isSigned() && !S.getLangOpts().CPlusPlus20) {
const Expr *E = S.Current->getExpr(OpPC);
// C++11 [expr.shift]p2: A signed left shift must have a non-negative
// operand, and must not overflow the corresponding unsigned type.
if (LHS.isNegative())
if (LHS.isNegative()) {
S.CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS.toAPSInt();
else if (LHS.toUnsigned().countLeadingZeros() < static_cast<unsigned>(RHS))
if (!S.noteUndefinedBehavior())
return false;
} else if (LHS.toUnsigned().countLeadingZeros() <
static_cast<unsigned>(RHS)) {
S.CCEDiag(E, diag::note_constexpr_lshift_discards);
if (!S.noteUndefinedBehavior())
return false;
}
}

// C++2a [expr.shift]p2: [P0907R4]:
Expand Down Expand Up @@ -2269,8 +2277,7 @@ inline bool DoShift(InterpState &S, CodePtr OpPC, LT &LHS, RT &RHS) {
// shift is not a constant expression.
const SourceInfo &Loc = S.Current->getSource(OpPC);
S.CCEDiag(Loc, diag::note_constexpr_negative_shift) << RHS.toAPSInt();
if (S.getLangOpts().CPlusPlus11 && S.getEvalStatus().Diag &&
!S.getEvalStatus().Diag->empty())
if (!S.noteUndefinedBehavior())
return false;
RHS = -RHS;
return DoShift < LT, RT,
Expand All @@ -2286,8 +2293,7 @@ inline bool DoShift(InterpState &S, CodePtr OpPC, LT &LHS, RT &RHS) {
// E1 x 2^E2 module 2^N.
const SourceInfo &Loc = S.Current->getSource(OpPC);
S.CCEDiag(Loc, diag::note_constexpr_lshift_of_negative) << LHS.toAPSInt();
if (S.getLangOpts().CPlusPlus11 && S.getEvalStatus().Diag &&
!S.getEvalStatus().Diag->empty())
if (!S.noteUndefinedBehavior())
return false;
}
}
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/AST/ItaniumMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5179,6 +5179,14 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity,
Diags.Report(DiagID);
return;
}
case UETT_PtrAuthTypeDiscriminator: {
DiagnosticsEngine &Diags = Context.getDiags();
unsigned DiagID = Diags.getCustomDiagID(
DiagnosticsEngine::Error,
"cannot yet mangle __builtin_ptrauth_type_discriminator expression");
Diags.Report(E->getExprLoc(), DiagID);
return;
}
case UETT_VecStep: {
DiagnosticsEngine &Diags = Context.getDiags();
unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
Expand Down
217 changes: 86 additions & 131 deletions clang/lib/AST/MicrosoftMangle.cpp

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion clang/lib/Basic/Targets/NVPTX.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ class LLVM_LIBRARY_VISIBILITY NVPTXTargetInfo : public TargetInfo {
}

BuiltinVaListKind getBuiltinVaListKind() const override {
return TargetInfo::VoidPtrBuiltinVaList;
return TargetInfo::CharPtrBuiltinVaList;
}

bool isValidCPUName(StringRef Name) const override {
Expand Down
15 changes: 9 additions & 6 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14523,12 +14523,7 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
// TODO: If we had a "freeze" IR instruction to generate a fixed undef
// value, we should use that here instead of a zero.
return llvm::Constant::getNullValue(ConvertType(E->getType()));
case X86::BI__builtin_ia32_vec_init_v8qi:
case X86::BI__builtin_ia32_vec_init_v4hi:
case X86::BI__builtin_ia32_vec_init_v2si:
return Builder.CreateBitCast(BuildVector(Ops),
llvm::Type::getX86_MMXTy(getLLVMContext()));
case X86::BI__builtin_ia32_vec_ext_v2si:
case X86::BI__builtin_ia32_vec_ext_v4hi:
case X86::BI__builtin_ia32_vec_ext_v16qi:
case X86::BI__builtin_ia32_vec_ext_v8hi:
case X86::BI__builtin_ia32_vec_ext_v4si:
Expand All @@ -14546,6 +14541,7 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
// Otherwise we could just do this in the header file.
return Builder.CreateExtractElement(Ops[0], Index);
}
case X86::BI__builtin_ia32_vec_set_v4hi:
case X86::BI__builtin_ia32_vec_set_v16qi:
case X86::BI__builtin_ia32_vec_set_v8hi:
case X86::BI__builtin_ia32_vec_set_v4si:
Expand Down Expand Up @@ -21567,6 +21563,13 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_extract_lane_f16x8);
return Builder.CreateCall(Callee, {Vector, Index});
}
case WebAssembly::BI__builtin_wasm_replace_lane_f16x8: {
Value *Vector = EmitScalarExpr(E->getArg(0));
Value *Index = EmitScalarExpr(E->getArg(1));
Value *Val = EmitScalarExpr(E->getArg(2));
Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_replace_lane_f16x8);
return Builder.CreateCall(Callee, {Vector, Index, Val});
}
case WebAssembly::BI__builtin_wasm_table_get: {
assert(E->getArg(0)->getType()->isArrayType());
Value *Table = EmitArrayToPointerDecay(E->getArg(0)).emitRawPointer(*this);
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2025,6 +2025,9 @@ static void getTrivialDefaultFunctionAttributes(
FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
}

if (CodeGenOpts.SaveRegParams && !AttrOnCallSite)
FuncAttrs.addAttribute("save-reg-params");

for (StringRef Attr : CodeGenOpts.DefaultFunctionAttrs) {
StringRef Var, Value;
std::tie(Var, Value) = Attr.split('=');
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1695,7 +1695,8 @@ void CGOpenMPRuntimeGPU::emitReduction(
CGF.AllocaInsertPt->getIterator());
InsertPointTy CodeGenIP(CGF.Builder.GetInsertBlock(),
CGF.Builder.GetInsertPoint());
llvm::OpenMPIRBuilder::LocationDescription OmpLoc(CodeGenIP);
llvm::OpenMPIRBuilder::LocationDescription OmpLoc(
CodeGenIP, CGF.SourceLocToDebugLoc(Loc));
llvm::SmallVector<llvm::OpenMPIRBuilder::ReductionInfo> ReductionInfos;

CodeGenFunction::OMPPrivateScope Scope(CGF);
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Driver/ToolChains/AIX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,9 @@ void AIX::addClangTargetOptions(
options::OPT_mtocdata))
addTocDataOptions(Args, CC1Args, getDriver());

if (Args.hasArg(options::OPT_msave_reg_params))
CC1Args.push_back("-msave-reg-params");

if (Args.hasFlag(options::OPT_fxl_pragma_pack,
options::OPT_fno_xl_pragma_pack, true))
CC1Args.push_back("-fxl-pragma-pack");
Expand Down
104 changes: 62 additions & 42 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1512,6 +1512,10 @@ static void handlePAuthABI(const ArgList &DriverArgs, ArgStringList &CC1Args) {
options::OPT_fno_ptrauth_vtable_pointer_type_discrimination))
CC1Args.push_back("-fptrauth-vtable-pointer-type-discrimination");

if (!DriverArgs.hasArg(options::OPT_fptrauth_indirect_gotos,
options::OPT_fno_ptrauth_indirect_gotos))
CC1Args.push_back("-fptrauth-indirect-gotos");

if (!DriverArgs.hasArg(options::OPT_fptrauth_init_fini,
options::OPT_fno_ptrauth_init_fini))
CC1Args.push_back("-fptrauth-init-fini");
Expand Down Expand Up @@ -1839,6 +1843,9 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args,
Args.addOptInFlag(
CmdArgs, options::OPT_fptrauth_vtable_pointer_type_discrimination,
options::OPT_fno_ptrauth_vtable_pointer_type_discrimination);
Args.addOptInFlag(
CmdArgs, options::OPT_fptrauth_type_info_vtable_pointer_discrimination,
options::OPT_fno_ptrauth_type_info_vtable_pointer_discrimination);
Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_init_fini,
options::OPT_fno_ptrauth_init_fini);
Args.addOptInFlag(
Expand Down Expand Up @@ -2867,6 +2874,7 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
// If one wasn't given by the user, don't pass it here.
StringRef FPContract;
StringRef LastSeenFfpContractOption;
StringRef LastFpContractOverrideOption;
bool SeenUnsafeMathModeOption = false;
if (!JA.isDeviceOffloading(Action::OFK_Cuda) &&
!JA.isOffloading(Action::OFK_HIP))
Expand Down Expand Up @@ -2908,6 +2916,27 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
SeenUnsafeMathModeOption = true;
};

// Lambda to consolidate common handling for fp-contract
auto restoreFPContractState = [&]() {
// CUDA and HIP don't rely on the frontend to pass an ffp-contract option.
// For other targets, if the state has been changed by one of the
// unsafe-math umbrella options a subsequent -fno-fast-math or
// -fno-unsafe-math-optimizations option reverts to the last value seen for
// the -ffp-contract option or "on" if we have not seen the -ffp-contract
// option. If we have not seen an unsafe-math option or -ffp-contract,
// we leave the FPContract state unchanged.
if (!JA.isDeviceOffloading(Action::OFK_Cuda) &&
!JA.isOffloading(Action::OFK_HIP)) {
if (LastSeenFfpContractOption != "")
FPContract = LastSeenFfpContractOption;
else if (SeenUnsafeMathModeOption)
FPContract = "on";
}
// In this case, we're reverting to the last explicit fp-contract option
// or the platform default
LastFpContractOverrideOption = "";
};

if (const Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
CmdArgs.push_back("-mlimit-float-precision");
CmdArgs.push_back(A->getValue());
Expand Down Expand Up @@ -3009,7 +3038,6 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
AssociativeMath = false;
ReciprocalMath = false;
SignedZeros = true;
FPContract = "on";

StringRef Val = A->getValue();
if (OFastEnabled && Val != "fast") {
Expand All @@ -3026,14 +3054,18 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
if (Val == "fast") {
FPModel = Val;
applyFastMath();
// applyFastMath sets fp-contract="fast"
LastFpContractOverrideOption = "-ffp-model=fast";
} else if (Val == "precise") {
FPModel = Val;
FPContract = "on";
LastFpContractOverrideOption = "-ffp-model=precise";
} else if (Val == "strict") {
StrictFPModel = true;
FPExceptionBehavior = "strict";
FPModel = Val;
FPContract = "off";
LastFpContractOverrideOption = "-ffp-model=strict";
TrappingMath = true;
RoundingFPMath = true;
} else
Expand Down Expand Up @@ -3112,8 +3144,15 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
StringRef Val = A->getValue();
if (Val == "fast" || Val == "on" || Val == "off" ||
Val == "fast-honor-pragmas") {
if (Val != FPContract && LastFpContractOverrideOption != "") {
D.Diag(clang::diag::warn_drv_overriding_option)
<< LastFpContractOverrideOption
<< Args.MakeArgString("-ffp-contract=" + Val);
}

FPContract = Val;
LastSeenFfpContractOption = Val;
LastFpContractOverrideOption = "";
} else
D.Diag(diag::err_drv_unsupported_option_argument)
<< A->getSpelling() << Val;
Expand Down Expand Up @@ -3192,32 +3231,29 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
TrappingMath = false;
FPExceptionBehavior = "";
FPContract = "fast";
LastFpContractOverrideOption = "-funsafe-math-optimizations";
SeenUnsafeMathModeOption = true;
break;
case options::OPT_fno_unsafe_math_optimizations:
AssociativeMath = false;
ReciprocalMath = false;
SignedZeros = true;
ApproxFunc = false;

if (!JA.isDeviceOffloading(Action::OFK_Cuda) &&
!JA.isOffloading(Action::OFK_HIP)) {
if (LastSeenFfpContractOption != "") {
FPContract = LastSeenFfpContractOption;
} else if (SeenUnsafeMathModeOption)
FPContract = "on";
}
restoreFPContractState();
break;

case options::OPT_Ofast:
// If -Ofast is the optimization level, then -ffast-math should be enabled
if (!OFastEnabled)
continue;
[[fallthrough]];
case options::OPT_ffast_math: {
case options::OPT_ffast_math:
applyFastMath();
if (A->getOption().getID() == options::OPT_Ofast)
LastFpContractOverrideOption = "-Ofast";
else
LastFpContractOverrideOption = "-ffast-math";
break;
}
case options::OPT_fno_fast_math:
HonorINFs = true;
HonorNaNs = true;
Expand All @@ -3229,16 +3265,11 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
ReciprocalMath = false;
ApproxFunc = false;
SignedZeros = true;
// -fno_fast_math restores default fpcontract handling
if (!JA.isDeviceOffloading(Action::OFK_Cuda) &&
!JA.isOffloading(Action::OFK_HIP)) {
if (LastSeenFfpContractOption != "") {
FPContract = LastSeenFfpContractOption;
} else if (SeenUnsafeMathModeOption)
FPContract = "on";
}
restoreFPContractState();
LastFpContractOverrideOption = "";
break;
}
} // End switch (A->getOption().getID())

// The StrictFPModel local variable is needed to report warnings
// in the way we intend. If -ffp-model=strict has been used, we
// want to report a warning for the next option encountered that
Expand All @@ -3256,12 +3287,17 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
else {
StrictFPModel = false;
FPModel = "";
// The warning for -ffp-contract would have been reported by the
// OPT_ffp_contract_EQ handler above. A special check here is needed
// to avoid duplicating the warning.
auto RHS = (A->getNumValues() == 0)
? A->getSpelling()
: Args.MakeArgString(A->getSpelling() + A->getValue());
if (RHS != "-ffp-model=strict")
D.Diag(clang::diag::warn_drv_overriding_option)
<< "-ffp-model=strict" << RHS;
if (A->getSpelling() != "-ffp-contract=") {
if (RHS != "-ffp-model=strict")
D.Diag(clang::diag::warn_drv_overriding_option)
<< "-ffp-model=strict" << RHS;
}
}
}

Expand Down Expand Up @@ -3343,21 +3379,8 @@ static void RenderFloatingPointOptions(const ToolChain &TC, const Driver &D,
// individual features enabled by -ffast-math instead of the option itself as
// that's consistent with gcc's behaviour.
if (!HonorINFs && !HonorNaNs && !MathErrno && AssociativeMath && ApproxFunc &&
ReciprocalMath && !SignedZeros && !TrappingMath && !RoundingFPMath) {
ReciprocalMath && !SignedZeros && !TrappingMath && !RoundingFPMath)
CmdArgs.push_back("-ffast-math");
if (FPModel == "fast") {
if (FPContract == "fast")
// All set, do nothing.
;
else if (FPContract.empty())
// Enable -ffp-contract=fast
CmdArgs.push_back(Args.MakeArgString("-ffp-contract=fast"));
else
D.Diag(clang::diag::warn_drv_overriding_option)
<< "-ffp-model=fast"
<< Args.MakeArgString("-ffp-contract=" + FPContract);
}
}

// Handle __FINITE_MATH_ONLY__ similarly.
if (!HonorINFs && !HonorNaNs)
Expand Down Expand Up @@ -4717,11 +4740,8 @@ renderDebugOptions(const ToolChain &TC, const Driver &D, const llvm::Triple &T,

// -gdwarf-aranges turns on the emission of the aranges section in the
// backend.
// Always enabled for SCE tuning.
bool NeedAranges = DebuggerTuning == llvm::DebuggerKind::SCE;
if (const Arg *A = Args.getLastArg(options::OPT_gdwarf_aranges))
NeedAranges = checkDebugInfoOption(A, Args, D, TC) || NeedAranges;
if (NeedAranges) {
if (const Arg *A = Args.getLastArg(options::OPT_gdwarf_aranges);
A && checkDebugInfoOption(A, Args, D, TC)) {
CmdArgs.push_back("-mllvm");
CmdArgs.push_back("-generate-arange-section");
}
Expand Down
8 changes: 0 additions & 8 deletions clang/lib/Driver/ToolChains/PS4CPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,6 @@ void tools::PS4cpu::Linker::ConstructJob(Compilation &C, const JobAction &JA,
};

if (UseLTO) {
// We default to creating the arange section, but LTO does not. Enable it
// here.
AddCodeGenFlag("-generate-arange-section");

// This tells LTO to perform JustMyCode instrumentation.
if (UseJMC)
AddCodeGenFlag("-enable-jmc-instrument");
Expand Down Expand Up @@ -272,10 +268,6 @@ void tools::PS5cpu::Linker::ConstructJob(Compilation &C, const JobAction &JA,
};

if (UseLTO) {
// We default to creating the arange section, but LTO does not. Enable it
// here.
AddCodeGenFlag("-generate-arange-section");

// This tells LTO to perform JustMyCode instrumentation.
if (UseJMC)
AddCodeGenFlag("-enable-jmc-instrument");
Expand Down
41 changes: 22 additions & 19 deletions clang/lib/Headers/emmintrin.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,12 @@ typedef __bf16 __m128bh __attribute__((__vector_size__(16), __aligned__(16)));
#define __DEFAULT_FN_ATTRS \
__attribute__((__always_inline__, __nodebug__, \
__target__("sse2,no-evex512"), __min_vector_width__(128)))
#define __DEFAULT_FN_ATTRS_MMX \
__attribute__((__always_inline__, __nodebug__, \
__target__("mmx,sse2,no-evex512"), __min_vector_width__(64)))

#define __trunc64(x) \
(__m64) __builtin_shufflevector((__v2di)(x), __extension__(__v2di){}, 0)
#define __anyext128(x) \
(__m128i) __builtin_shufflevector((__v2si)(x), __extension__(__v2si){}, 0, \
1, -1, -1)

/// Adds lower double-precision values in both operands and returns the
/// sum in the lower 64 bits of the result. The upper 64 bits of the result
Expand Down Expand Up @@ -1486,8 +1489,8 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_cvttsd_si32(__m128d __a) {
/// \param __a
/// A 128-bit vector of [2 x double].
/// \returns A 64-bit vector of [2 x i32] containing the converted values.
static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX _mm_cvtpd_pi32(__m128d __a) {
return (__m64)__builtin_ia32_cvtpd2pi((__v2df)__a);
static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_cvtpd_pi32(__m128d __a) {
return __trunc64(__builtin_ia32_cvtpd2dq((__v2df)__a));
}

/// Converts the two double-precision floating-point elements of a
Expand All @@ -1505,8 +1508,8 @@ static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX _mm_cvtpd_pi32(__m128d __a) {
/// \param __a
/// A 128-bit vector of [2 x double].
/// \returns A 64-bit vector of [2 x i32] containing the converted values.
static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX _mm_cvttpd_pi32(__m128d __a) {
return (__m64)__builtin_ia32_cvttpd2pi((__v2df)__a);
static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_cvttpd_pi32(__m128d __a) {
return __trunc64(__builtin_ia32_cvttpd2dq((__v2df)__a));
}

/// Converts the two signed 32-bit integer elements of a 64-bit vector of
Expand All @@ -1520,8 +1523,8 @@ static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX _mm_cvttpd_pi32(__m128d __a) {
/// \param __a
/// A 64-bit vector of [2 x i32].
/// \returns A 128-bit vector of [2 x double] containing the converted values.
static __inline__ __m128d __DEFAULT_FN_ATTRS_MMX _mm_cvtpi32_pd(__m64 __a) {
return __builtin_ia32_cvtpi2pd((__v2si)__a);
static __inline__ __m128d __DEFAULT_FN_ATTRS _mm_cvtpi32_pd(__m64 __a) {
return (__m128d) __builtin_convertvector((__v2si)__a, __v2df);
}

/// Returns the low-order element of a 128-bit vector of [2 x double] as
Expand Down Expand Up @@ -2108,9 +2111,8 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_add_epi32(__m128i __a,
/// \param __b
/// A 64-bit integer.
/// \returns A 64-bit integer containing the sum of both parameters.
static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX _mm_add_si64(__m64 __a,
__m64 __b) {
return (__m64)__builtin_ia32_paddq((__v1di)__a, (__v1di)__b);
static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_add_si64(__m64 __a, __m64 __b) {
return (__m64)(((unsigned long long)__a) + ((unsigned long long)__b));
}

/// Adds the corresponding elements of two 128-bit vectors of [2 x i64],
Expand Down Expand Up @@ -2431,9 +2433,9 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_mullo_epi16(__m128i __a,
/// \param __b
/// A 64-bit integer containing one of the source operands.
/// \returns A 64-bit integer vector containing the product of both operands.
static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX _mm_mul_su32(__m64 __a,
__m64 __b) {
return __builtin_ia32_pmuludq((__v2si)__a, (__v2si)__b);
static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_mul_su32(__m64 __a, __m64 __b) {
return __trunc64(__builtin_ia32_pmuludq128((__v4si)__anyext128(__a),
(__v4si)__anyext128(__b)));
}

/// Multiplies 32-bit unsigned integer values contained in the lower
Expand Down Expand Up @@ -2539,9 +2541,8 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_sub_epi32(__m128i __a,
/// A 64-bit integer vector containing the subtrahend.
/// \returns A 64-bit integer vector containing the difference of the values in
/// the operands.
static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX _mm_sub_si64(__m64 __a,
__m64 __b) {
return (__m64)__builtin_ia32_psubq((__v1di)__a, (__v1di)__b);
static __inline__ __m64 __DEFAULT_FN_ATTRS _mm_sub_si64(__m64 __a, __m64 __b) {
return (__m64)((unsigned long long)__a - (unsigned long long)__b);
}

/// Subtracts the corresponding elements of two [2 x i64] vectors.
Expand Down Expand Up @@ -4889,8 +4890,10 @@ void _mm_pause(void);
#if defined(__cplusplus)
} // extern "C"
#endif

#undef __anyext128
#undef __trunc64
#undef __DEFAULT_FN_ATTRS
#undef __DEFAULT_FN_ATTRS_MMX

#define _MM_SHUFFLE2(x, y) (((x) << 1) | (y))

Expand Down
308 changes: 180 additions & 128 deletions clang/lib/Headers/mmintrin.h

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions clang/lib/Headers/ptrauth.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,23 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
#define ptrauth_string_discriminator(__string) \
__builtin_ptrauth_string_discriminator(__string)

/* Compute a constant discriminator from the given type.

The result can be used as the second argument to
ptrauth_blend_discriminator or the third argument to the
__ptrauth qualifier. It has type size_t.

If the type is a C++ member function pointer type, the result is
the discriminator used to signed member function pointers of that
type. If the type is a function, function pointer, or function
reference type, the result is the discriminator used to sign
functions of that type. It is ill-formed to use this macro with any
other type.

A call to this function is an integer constant expression. */
#define ptrauth_type_discriminator(__type) \
__builtin_ptrauth_type_discriminator(__type)

/* Compute a signature for the given pair of pointer-sized values.
The order of the arguments is significant.

Expand Down Expand Up @@ -289,6 +306,8 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
((ptrauth_extra_data_t)0); \
})

#define ptrauth_type_discriminator(__type) ((ptrauth_extra_data_t)0)

#define ptrauth_sign_generic_data(__value, __data) \
({ \
(void)__value; \
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Headers/stdatomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,11 @@ typedef _Atomic(uintmax_t) atomic_uintmax_t;

typedef struct atomic_flag { atomic_bool _Value; } atomic_flag;

#ifdef __cplusplus
#define ATOMIC_FLAG_INIT {false}
#else
#define ATOMIC_FLAG_INIT { 0 }
#endif

/* These should be provided by the libc implementation. */
#ifdef __cplusplus
Expand Down
96 changes: 58 additions & 38 deletions clang/lib/Headers/tmmintrin.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@
/* Define the default attributes for the functions in this file. */
#define __DEFAULT_FN_ATTRS \
__attribute__((__always_inline__, __nodebug__, \
__target__("ssse3,no-evex512"), __min_vector_width__(64)))
#define __DEFAULT_FN_ATTRS_MMX \
__attribute__((__always_inline__, __nodebug__, \
__target__("mmx,ssse3,no-evex512"), \
__min_vector_width__(64)))
__target__("ssse3,no-evex512"), __min_vector_width__(128)))

#define __trunc64(x) \
(__m64) __builtin_shufflevector((__v2di)(x), __extension__(__v2di){}, 0)
#define __anyext128(x) \
(__m128i) __builtin_shufflevector((__v2si)(x), __extension__(__v2si){}, 0, \
1, -1, -1)

/// Computes the absolute value of each of the packed 8-bit signed
/// integers in the source operand and stores the 8-bit unsigned integer
Expand All @@ -37,10 +39,10 @@
/// A 64-bit vector of [8 x i8].
/// \returns A 64-bit integer vector containing the absolute values of the
/// elements in the operand.
static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX
static __inline__ __m64 __DEFAULT_FN_ATTRS
_mm_abs_pi8(__m64 __a)
{
return (__m64)__builtin_ia32_pabsb((__v8qi)__a);
return (__m64)__builtin_elementwise_abs((__v8qs)__a);
}

/// Computes the absolute value of each of the packed 8-bit signed
Expand Down Expand Up @@ -73,10 +75,10 @@ _mm_abs_epi8(__m128i __a)
/// A 64-bit vector of [4 x i16].
/// \returns A 64-bit integer vector containing the absolute values of the
/// elements in the operand.
static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX
static __inline__ __m64 __DEFAULT_FN_ATTRS
_mm_abs_pi16(__m64 __a)
{
return (__m64)__builtin_ia32_pabsw((__v4hi)__a);
return (__m64)__builtin_elementwise_abs((__v4hi)__a);
}

/// Computes the absolute value of each of the packed 16-bit signed
Expand Down Expand Up @@ -109,10 +111,10 @@ _mm_abs_epi16(__m128i __a)
/// A 64-bit vector of [2 x i32].
/// \returns A 64-bit integer vector containing the absolute values of the
/// elements in the operand.
static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX
static __inline__ __m64 __DEFAULT_FN_ATTRS
_mm_abs_pi32(__m64 __a)
{
return (__m64)__builtin_ia32_pabsd((__v2si)__a);
return (__m64)__builtin_elementwise_abs((__v2si)__a);
}

/// Computes the absolute value of each of the packed 32-bit signed
Expand Down Expand Up @@ -177,7 +179,10 @@ _mm_abs_epi32(__m128i __a)
/// \returns A 64-bit integer vector containing the concatenated right-shifted
/// value.
#define _mm_alignr_pi8(a, b, n) \
((__m64)__builtin_ia32_palignr((__v8qi)(__m64)(a), (__v8qi)(__m64)(b), (n)))
((__m64)__builtin_shufflevector( \
__builtin_ia32_psrldqi128_byteshift( \
__builtin_shufflevector((__v1di)(a), (__v1di)(b), 1, 0), \
(n)), __extension__ (__v2di){}, 0))

/// Horizontally adds the adjacent pairs of values contained in 2 packed
/// 128-bit vectors of [8 x i16].
Expand Down Expand Up @@ -242,10 +247,11 @@ _mm_hadd_epi32(__m128i __a, __m128i __b)
/// destination.
/// \returns A 64-bit vector of [4 x i16] containing the horizontal sums of both
/// operands.
static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX
static __inline__ __m64 __DEFAULT_FN_ATTRS
_mm_hadd_pi16(__m64 __a, __m64 __b)
{
return (__m64)__builtin_ia32_phaddw((__v4hi)__a, (__v4hi)__b);
return __trunc64(__builtin_ia32_phaddw128(
(__v8hi)__builtin_shufflevector(__a, __b, 0, 1), (__v8hi){}));
}

/// Horizontally adds the adjacent pairs of values contained in 2 packed
Expand All @@ -265,10 +271,11 @@ _mm_hadd_pi16(__m64 __a, __m64 __b)
/// destination.
/// \returns A 64-bit vector of [2 x i32] containing the horizontal sums of both
/// operands.
static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX
static __inline__ __m64 __DEFAULT_FN_ATTRS
_mm_hadd_pi32(__m64 __a, __m64 __b)
{
return (__m64)__builtin_ia32_phaddd((__v2si)__a, (__v2si)__b);
return __trunc64(__builtin_ia32_phaddd128(
(__v4si)__builtin_shufflevector(__a, __b, 0, 1), (__v4si){}));
}

/// Horizontally adds, with saturation, the adjacent pairs of values contained
Expand Down Expand Up @@ -317,10 +324,11 @@ _mm_hadds_epi16(__m128i __a, __m128i __b)
/// destination.
/// \returns A 64-bit vector of [4 x i16] containing the horizontal saturated
/// sums of both operands.
static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX
static __inline__ __m64 __DEFAULT_FN_ATTRS
_mm_hadds_pi16(__m64 __a, __m64 __b)
{
return (__m64)__builtin_ia32_phaddsw((__v4hi)__a, (__v4hi)__b);
return __trunc64(__builtin_ia32_phaddsw128(
(__v8hi)__builtin_shufflevector(__a, __b, 0, 1), (__v8hi){}));
}

/// Horizontally subtracts the adjacent pairs of values contained in 2
Expand Down Expand Up @@ -386,10 +394,11 @@ _mm_hsub_epi32(__m128i __a, __m128i __b)
/// the destination.
/// \returns A 64-bit vector of [4 x i16] containing the horizontal differences
/// of both operands.
static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX
static __inline__ __m64 __DEFAULT_FN_ATTRS
_mm_hsub_pi16(__m64 __a, __m64 __b)
{
return (__m64)__builtin_ia32_phsubw((__v4hi)__a, (__v4hi)__b);
return __trunc64(__builtin_ia32_phsubw128(
(__v8hi)__builtin_shufflevector(__a, __b, 0, 1), (__v8hi){}));
}

/// Horizontally subtracts the adjacent pairs of values contained in 2
Expand All @@ -409,10 +418,11 @@ _mm_hsub_pi16(__m64 __a, __m64 __b)
/// the destination.
/// \returns A 64-bit vector of [2 x i32] containing the horizontal differences
/// of both operands.
static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX
static __inline__ __m64 __DEFAULT_FN_ATTRS
_mm_hsub_pi32(__m64 __a, __m64 __b)
{
return (__m64)__builtin_ia32_phsubd((__v2si)__a, (__v2si)__b);
return __trunc64(__builtin_ia32_phsubd128(
(__v4si)__builtin_shufflevector(__a, __b, 0, 1), (__v4si){}));
}

/// Horizontally subtracts, with saturation, the adjacent pairs of values
Expand Down Expand Up @@ -461,10 +471,11 @@ _mm_hsubs_epi16(__m128i __a, __m128i __b)
/// the destination.
/// \returns A 64-bit vector of [4 x i16] containing the horizontal saturated
/// differences of both operands.
static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX
static __inline__ __m64 __DEFAULT_FN_ATTRS
_mm_hsubs_pi16(__m64 __a, __m64 __b)
{
return (__m64)__builtin_ia32_phsubsw((__v4hi)__a, (__v4hi)__b);
return __trunc64(__builtin_ia32_phsubsw128(
(__v8hi)__builtin_shufflevector(__a, __b, 0, 1), (__v8hi){}));
}

/// Multiplies corresponding pairs of packed 8-bit unsigned integer
Expand Down Expand Up @@ -525,10 +536,11 @@ _mm_maddubs_epi16(__m128i __a, __m128i __b)
/// \a R1 := (\a __a2 * \a __b2) + (\a __a3 * \a __b3) \n
/// \a R2 := (\a __a4 * \a __b4) + (\a __a5 * \a __b5) \n
/// \a R3 := (\a __a6 * \a __b6) + (\a __a7 * \a __b7)
static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX
static __inline__ __m64 __DEFAULT_FN_ATTRS
_mm_maddubs_pi16(__m64 __a, __m64 __b)
{
return (__m64)__builtin_ia32_pmaddubsw((__v8qi)__a, (__v8qi)__b);
return __trunc64(__builtin_ia32_pmaddubsw128((__v16qi)__anyext128(__a),
(__v16qi)__anyext128(__b)));
}

/// Multiplies packed 16-bit signed integer values, truncates the 32-bit
Expand Down Expand Up @@ -565,10 +577,11 @@ _mm_mulhrs_epi16(__m128i __a, __m128i __b)
/// A 64-bit vector of [4 x i16] containing one of the source operands.
/// \returns A 64-bit vector of [4 x i16] containing the rounded and scaled
/// products of both operands.
static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX
static __inline__ __m64 __DEFAULT_FN_ATTRS
_mm_mulhrs_pi16(__m64 __a, __m64 __b)
{
return (__m64)__builtin_ia32_pmulhrsw((__v4hi)__a, (__v4hi)__b);
return __trunc64(__builtin_ia32_pmulhrsw128((__v8hi)__anyext128(__a),
(__v8hi)__anyext128(__b)));
}

/// Copies the 8-bit integers from a 128-bit integer vector to the
Expand Down Expand Up @@ -614,12 +627,15 @@ _mm_shuffle_epi8(__m128i __a, __m128i __b)
/// 1: Clear the corresponding byte in the destination. \n
/// 0: Copy the selected source byte to the corresponding byte in the
/// destination. \n
/// Bits [3:0] select the source byte to be copied.
/// Bits [2:0] select the source byte to be copied.
/// \returns A 64-bit integer vector containing the copied or cleared values.
static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX
static __inline__ __m64 __DEFAULT_FN_ATTRS
_mm_shuffle_pi8(__m64 __a, __m64 __b)
{
return (__m64)__builtin_ia32_pshufb((__v8qi)__a, (__v8qi)__b);
return __trunc64(__builtin_ia32_pshufb128(
(__v16qi)__builtin_shufflevector(
(__v2si)(__a), __extension__ (__v2si){}, 0, 1, 0, 1),
(__v16qi)__anyext128(__b)));
}

/// For each 8-bit integer in the first source operand, perform one of
Expand Down Expand Up @@ -720,10 +736,11 @@ _mm_sign_epi32(__m128i __a, __m128i __b)
/// A 64-bit integer vector containing control bytes corresponding to
/// positions in the destination.
/// \returns A 64-bit integer vector containing the resultant values.
static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX
static __inline__ __m64 __DEFAULT_FN_ATTRS
_mm_sign_pi8(__m64 __a, __m64 __b)
{
return (__m64)__builtin_ia32_psignb((__v8qi)__a, (__v8qi)__b);
return __trunc64(__builtin_ia32_psignb128((__v16qi)__anyext128(__a),
(__v16qi)__anyext128(__b)));
}

/// For each 16-bit integer in the first source operand, perform one of
Expand All @@ -746,10 +763,11 @@ _mm_sign_pi8(__m64 __a, __m64 __b)
/// A 64-bit integer vector containing control words corresponding to
/// positions in the destination.
/// \returns A 64-bit integer vector containing the resultant values.
static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX
static __inline__ __m64 __DEFAULT_FN_ATTRS
_mm_sign_pi16(__m64 __a, __m64 __b)
{
return (__m64)__builtin_ia32_psignw((__v4hi)__a, (__v4hi)__b);
return __trunc64(__builtin_ia32_psignw128((__v8hi)__anyext128(__a),
(__v8hi)__anyext128(__b)));
}

/// For each 32-bit integer in the first source operand, perform one of
Expand All @@ -772,13 +790,15 @@ _mm_sign_pi16(__m64 __a, __m64 __b)
/// A 64-bit integer vector containing two control doublewords corresponding
/// to positions in the destination.
/// \returns A 64-bit integer vector containing the resultant values.
static __inline__ __m64 __DEFAULT_FN_ATTRS_MMX
static __inline__ __m64 __DEFAULT_FN_ATTRS
_mm_sign_pi32(__m64 __a, __m64 __b)
{
return (__m64)__builtin_ia32_psignd((__v2si)__a, (__v2si)__b);
return __trunc64(__builtin_ia32_psignd128((__v4si)__anyext128(__a),
(__v4si)__anyext128(__b)));
}

#undef __anyext128
#undef __trunc64
#undef __DEFAULT_FN_ATTRS
#undef __DEFAULT_FN_ATTRS_MMX

#endif /* __TMMINTRIN_H */
193 changes: 97 additions & 96 deletions clang/lib/Headers/xmmintrin.h

Large diffs are not rendered by default.

18 changes: 11 additions & 7 deletions clang/lib/Lex/PPMacroExpansion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@
#include <cstddef>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <optional>
#include <sstream>
#include <string>
#include <tuple>
#include <utility>
Expand Down Expand Up @@ -1721,11 +1723,13 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
Diag(Tok.getLocation(), diag::warn_pp_date_time);
// MSVC, ICC, GCC, VisualAge C++ extension. The generated string should be
// of the form "Ddd Mmm dd hh::mm::ss yyyy", which is returned by asctime.
const char *Result;
std::string Result;
std::stringstream TmpStream;
TmpStream.imbue(std::locale("C"));
if (getPreprocessorOpts().SourceDateEpoch) {
time_t TT = *getPreprocessorOpts().SourceDateEpoch;
std::tm *TM = std::gmtime(&TT);
Result = asctime(TM);
TmpStream << std::put_time(TM, "%a %b %e %T %Y");
} else {
// Get the file that we are lexing out of. If we're currently lexing from
// a macro, dig into the include stack.
Expand All @@ -1735,13 +1739,13 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
if (CurFile) {
time_t TT = CurFile->getModificationTime();
struct tm *TM = localtime(&TT);
Result = asctime(TM);
} else {
Result = "??? ??? ?? ??:??:?? ????\n";
TmpStream << std::put_time(TM, "%a %b %e %T %Y");
}
}
// Surround the string with " and strip the trailing newline.
OS << '"' << StringRef(Result).drop_back() << '"';
Result = TmpStream.str();
if (Result.empty())
Result = "??? ??? ?? ??:??:?? ????";
OS << '"' << Result << '"';
Tok.setKind(tok::string_literal);
} else if (II == Ident__FLT_EVAL_METHOD__) {
// __FLT_EVAL_METHOD__ is set to the default value.
Expand Down
23 changes: 23 additions & 0 deletions clang/lib/Parse/ParseExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,26 @@ bool Parser::isRevertibleTypeTrait(const IdentifierInfo *II,
return false;
}

ExprResult Parser::ParseBuiltinPtrauthTypeDiscriminator() {
SourceLocation Loc = ConsumeToken();

BalancedDelimiterTracker T(*this, tok::l_paren);
if (T.expectAndConsume())
return ExprError();

TypeResult Ty = ParseTypeName();
if (Ty.isInvalid()) {
SkipUntil(tok::r_paren, StopAtSemi);
return ExprError();
}

SourceLocation EndLoc = Tok.getLocation();
T.consumeClose();
return Actions.ActOnUnaryExprOrTypeTraitExpr(
Loc, UETT_PtrAuthTypeDiscriminator,
/*isType=*/true, Ty.get().getAsOpaquePtr(), SourceRange(Loc, EndLoc));
}

/// Parse a cast-expression, or, if \pisUnaryExpression is true, parse
/// a unary-expression.
///
Expand Down Expand Up @@ -1806,6 +1826,9 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
Res = ParseArrayTypeTrait();
break;

case tok::kw___builtin_ptrauth_type_discriminator:
return ParseBuiltinPtrauthTypeDiscriminator();

case tok::kw___is_lvalue_expr:
case tok::kw___is_rvalue_expr:
if (NotPrimaryExpression)
Expand Down
9 changes: 9 additions & 0 deletions clang/lib/Sema/CheckExprLifetime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//

#include "CheckExprLifetime.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/DiagnosticSema.h"
#include "clang/Sema/Initialization.h"
Expand Down Expand Up @@ -548,6 +549,14 @@ static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path,
EnableLifetimeWarnings);
}

if (auto *M = dyn_cast<MemberExpr>(Init)) {
// Lifetime of a non-reference type field is same as base object.
if (auto *F = dyn_cast<FieldDecl>(M->getMemberDecl());
F && !F->getType()->isReferenceType())
visitLocalsRetainedByInitializer(Path, M->getBase(), Visit, true,
EnableLifetimeWarnings);
}

if (isa<CallExpr>(Init)) {
if (EnableLifetimeWarnings)
handleGslAnnotatedTypes(Path, Init, Visit);
Expand Down
10 changes: 7 additions & 3 deletions clang/lib/Sema/SemaChecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1489,14 +1489,18 @@ enum PointerAuthOpKind {
};
}

static bool checkPointerAuthEnabled(Sema &S, Expr *E) {
if (S.getLangOpts().PointerAuthIntrinsics)
bool Sema::checkPointerAuthEnabled(SourceLocation Loc, SourceRange Range) {
if (getLangOpts().PointerAuthIntrinsics)
return false;

S.Diag(E->getExprLoc(), diag::err_ptrauth_disabled) << E->getSourceRange();
Diag(Loc, diag::err_ptrauth_disabled) << Range;
return true;
}

static bool checkPointerAuthEnabled(Sema &S, Expr *E) {
return S.checkPointerAuthEnabled(E->getExprLoc(), E->getSourceRange());
}

static bool checkPointerAuthKey(Sema &S, Expr *&Arg) {
// Convert it to type 'int'.
if (convertArgumentToType(S, Arg, S.Context.IntTy))
Expand Down
10 changes: 10 additions & 0 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1537,6 +1537,16 @@ static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
<< Idx.getSourceIndex() << Ex->getSourceRange();
return;
}
} else if (K == OwnershipAttr::Takes &&
I->getOwnKind() == OwnershipAttr::Takes) {
if (I->getModule()->getName() != ModuleName) {
S.Diag(I->getLocation(), diag::err_ownership_takes_class_mismatch)
<< I->getModule()->getName();
S.Diag(AL.getLoc(), diag::note_ownership_takes_class_mismatch)
<< ModuleName << Ex->getSourceRange();

return;
}
}
}
OwnershipArgs.push_back(Idx);
Expand Down
23 changes: 21 additions & 2 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4117,6 +4117,21 @@ static bool CheckVectorElementsTraitOperandType(Sema &S, QualType T,
return false;
}

static bool checkPtrAuthTypeDiscriminatorOperandType(Sema &S, QualType T,
SourceLocation Loc,
SourceRange ArgRange) {
if (S.checkPointerAuthEnabled(Loc, ArgRange))
return true;

if (!T->isFunctionType() && !T->isFunctionPointerType() &&
!T->isFunctionReferenceType() && !T->isMemberFunctionPointerType()) {
S.Diag(Loc, diag::err_ptrauth_type_disc_undiscriminated) << T << ArgRange;
return true;
}

return false;
}

static bool CheckExtensionTraitOperandType(Sema &S, QualType T,
SourceLocation Loc,
SourceRange ArgRange,
Expand Down Expand Up @@ -4511,6 +4526,10 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(QualType ExprType,
return CheckVectorElementsTraitOperandType(*this, ExprType, OpLoc,
ExprRange);

if (ExprKind == UETT_PtrAuthTypeDiscriminator)
return checkPtrAuthTypeDiscriminatorOperandType(*this, ExprType, OpLoc,
ExprRange);

// Explicitly list some types as extensions.
if (!CheckExtensionTraitOperandType(*this, ExprType, OpLoc, ExprRange,
ExprKind))
Expand Down Expand Up @@ -5711,7 +5730,6 @@ static bool isParenthetizedAndQualifiedAddressOfExpr(Expr *Fn) {
if (!UO || UO->getOpcode() != clang::UO_AddrOf)
return false;
if (auto *DRE = dyn_cast<DeclRefExpr>(UO->getSubExpr()->IgnoreParens())) {
assert(isa<FunctionDecl>(DRE->getDecl()) && "expected a function");
return DRE->hasQualifier();
}
if (auto *OVL = dyn_cast<OverloadExpr>(UO->getSubExpr()->IgnoreParens()))
Expand Down Expand Up @@ -17027,7 +17045,8 @@ Sema::VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result,
// not a constant expression as a side-effect.
bool Folded =
E->EvaluateAsRValue(EvalResult, Context, /*isConstantContext*/ true) &&
EvalResult.Val.isInt() && !EvalResult.HasSideEffects;
EvalResult.Val.isInt() && !EvalResult.HasSideEffects &&
(!getLangOpts().CPlusPlus || !EvalResult.HasUndefinedBehavior);

if (!isa<ConstantExpr>(E))
E = ConstantExpr::Create(Context, E, EvalResult.Val);
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/Sema/SemaExprObjC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3206,9 +3206,10 @@ ExprResult SemaObjC::BuildInstanceMessage(
}
if (!isDesignatedInitChain) {
const ObjCMethodDecl *InitMethod = nullptr;
auto *CurMD = SemaRef.getCurMethodDecl();
assert(CurMD && "Current method declaration should not be null");
bool isDesignated =
SemaRef.getCurMethodDecl()->isDesignatedInitializerForTheInterface(
&InitMethod);
CurMD->isDesignatedInitializerForTheInterface(&InitMethod);
assert(isDesignated && InitMethod);
(void)isDesignated;
Diag(SelLoc, SuperLoc.isValid() ?
Expand Down
56 changes: 24 additions & 32 deletions clang/lib/Sema/SemaOverload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Casting.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdlib>
#include <optional>
Expand Down Expand Up @@ -6857,10 +6858,7 @@ void Sema::AddOverloadCandidate(
Candidate.Viable = true;
Candidate.RewriteKind =
CandidateSet.getRewriteInfo().getRewriteKind(Function, PO);
Candidate.IsSurrogate = false;
Candidate.IsADLCandidate = IsADLCandidate;
Candidate.IgnoreObjectArgument = false;
Candidate.TookAddressOfOverload = false;
Candidate.ExplicitCallArguments = Args.size();

// Explicit functions are not actually candidates at all if we're not
Expand Down Expand Up @@ -7422,8 +7420,6 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,
Candidate.Function = Method;
Candidate.RewriteKind =
CandidateSet.getRewriteInfo().getRewriteKind(Method, PO);
Candidate.IsSurrogate = false;
Candidate.IgnoreObjectArgument = false;
Candidate.TookAddressOfOverload =
CandidateSet.getKind() == OverloadCandidateSet::CSK_AddressOfOverloadSet;
Candidate.ExplicitCallArguments = Args.size();
Expand Down Expand Up @@ -7617,7 +7613,6 @@ void Sema::AddMethodTemplateCandidate(
Candidate.IgnoreObjectArgument =
cast<CXXMethodDecl>(Candidate.Function)->isStatic() ||
ObjectType.isNull();
Candidate.TookAddressOfOverload = false;
Candidate.ExplicitCallArguments = Args.size();
if (Result == TemplateDeductionResult::NonDependentConversionFailure)
Candidate.FailureKind = ovl_fail_bad_conversion;
Expand Down Expand Up @@ -7705,7 +7700,6 @@ void Sema::AddTemplateOverloadCandidate(
Candidate.IgnoreObjectArgument =
isa<CXXMethodDecl>(Candidate.Function) &&
!isa<CXXConstructorDecl>(Candidate.Function);
Candidate.TookAddressOfOverload = false;
Candidate.ExplicitCallArguments = Args.size();
if (Result == TemplateDeductionResult::NonDependentConversionFailure)
Candidate.FailureKind = ovl_fail_bad_conversion;
Expand Down Expand Up @@ -7886,9 +7880,6 @@ void Sema::AddConversionCandidate(
OverloadCandidate &Candidate = CandidateSet.addCandidate(1);
Candidate.FoundDecl = FoundDecl;
Candidate.Function = Conversion;
Candidate.IsSurrogate = false;
Candidate.IgnoreObjectArgument = false;
Candidate.TookAddressOfOverload = false;
Candidate.FinalConversion.setAsIdentityConversion();
Candidate.FinalConversion.setFromType(ConvType);
Candidate.FinalConversion.setAllToTypes(ToType);
Expand Down Expand Up @@ -8084,9 +8075,6 @@ void Sema::AddTemplateConversionCandidate(
Candidate.Function = FunctionTemplate->getTemplatedDecl();
Candidate.Viable = false;
Candidate.FailureKind = ovl_fail_bad_deduction;
Candidate.IsSurrogate = false;
Candidate.IgnoreObjectArgument = false;
Candidate.TookAddressOfOverload = false;
Candidate.ExplicitCallArguments = 1;
Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result,
Info);
Expand Down Expand Up @@ -8119,10 +8107,8 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
Candidate.FoundDecl = FoundDecl;
Candidate.Function = nullptr;
Candidate.Surrogate = Conversion;
Candidate.Viable = true;
Candidate.IsSurrogate = true;
Candidate.IgnoreObjectArgument = false;
Candidate.TookAddressOfOverload = false;
Candidate.Viable = true;
Candidate.ExplicitCallArguments = Args.size();

// Determine the implicit conversion sequence for the implicit
Expand Down Expand Up @@ -8328,9 +8314,6 @@ void Sema::AddBuiltinCandidate(QualType *ParamTys, ArrayRef<Expr *> Args,
OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size());
Candidate.FoundDecl = DeclAccessPair::make(nullptr, AS_none);
Candidate.Function = nullptr;
Candidate.IsSurrogate = false;
Candidate.IgnoreObjectArgument = false;
Candidate.TookAddressOfOverload = false;
std::copy(ParamTys, ParamTys + Args.size(), Candidate.BuiltinParamTypes);

// Determine the implicit conversion sequences for each of the
Expand Down Expand Up @@ -9995,8 +9978,9 @@ Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,
CandEnd = CandidateSet.end();
Cand != CandEnd; ++Cand)
if (Cand->Function) {
Fns.erase(Cand->Function);
if (FunctionTemplateDecl *FunTmpl = Cand->Function->getPrimaryTemplate())
FunctionDecl *Fn = Cand->Function;
Fns.erase(Fn);
if (FunctionTemplateDecl *FunTmpl = Fn->getPrimaryTemplate())
Fns.erase(FunTmpl);
}

Expand Down Expand Up @@ -11350,8 +11334,7 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand,
}
}

if (TakingCandidateAddress &&
!checkAddressOfCandidateIsAvailable(S, Cand->Function))
if (TakingCandidateAddress && !checkAddressOfCandidateIsAvailable(S, Fn))
return;

// Emit the generic diagnostic and, optionally, add the hints to it.
Expand All @@ -11377,6 +11360,7 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand,
/// over a candidate in any candidate set.
static bool CheckArityMismatch(Sema &S, OverloadCandidate *Cand,
unsigned NumArgs, bool IsAddressOf = false) {
assert(Cand->Function && "Candidate is required to be a function.");
FunctionDecl *Fn = Cand->Function;
unsigned MinParams = Fn->getMinRequiredExplicitArguments() +
((IsAddressOf && !Fn->isStatic()) ? 1 : 0);
Expand Down Expand Up @@ -11467,8 +11451,10 @@ static void DiagnoseArityMismatch(Sema &S, NamedDecl *Found, Decl *D,
/// Arity mismatch diagnosis specific to a function overload candidate.
static void DiagnoseArityMismatch(Sema &S, OverloadCandidate *Cand,
unsigned NumFormalArgs) {
assert(Cand->Function && "Candidate must be a function");
FunctionDecl *Fn = Cand->Function;
if (!CheckArityMismatch(S, Cand, NumFormalArgs, Cand->TookAddressOfOverload))
DiagnoseArityMismatch(S, Cand->FoundDecl, Cand->Function, NumFormalArgs,
DiagnoseArityMismatch(S, Cand->FoundDecl, Fn, NumFormalArgs,
Cand->TookAddressOfOverload);
}

Expand Down Expand Up @@ -11768,19 +11754,22 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
static void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand,
unsigned NumArgs,
bool TakingCandidateAddress) {
assert(Cand->Function && "Candidate must be a function");
FunctionDecl *Fn = Cand->Function;
TemplateDeductionResult TDK = Cand->DeductionFailure.getResult();
if (TDK == TemplateDeductionResult::TooFewArguments ||
TDK == TemplateDeductionResult::TooManyArguments) {
if (CheckArityMismatch(S, Cand, NumArgs))
return;
}
DiagnoseBadDeduction(S, Cand->FoundDecl, Cand->Function, // pattern
DiagnoseBadDeduction(S, Cand->FoundDecl, Fn, // pattern
Cand->DeductionFailure, NumArgs, TakingCandidateAddress);
}

/// CUDA: diagnose an invalid call across targets.
static void DiagnoseBadTarget(Sema &S, OverloadCandidate *Cand) {
FunctionDecl *Caller = S.getCurFunctionDecl(/*AllowLambda=*/true);
assert(Cand->Function && "Candidate must be a Function.");
FunctionDecl *Callee = Cand->Function;

CUDAFunctionTarget CallerTarget = S.CUDA().IdentifyTarget(Caller),
Expand Down Expand Up @@ -11838,6 +11827,7 @@ static void DiagnoseBadTarget(Sema &S, OverloadCandidate *Cand) {
}

static void DiagnoseFailedEnableIfAttr(Sema &S, OverloadCandidate *Cand) {
assert(Cand->Function && "Candidate must be a function");
FunctionDecl *Callee = Cand->Function;
EnableIfAttr *Attr = static_cast<EnableIfAttr*>(Cand->DeductionFailure.Data);

Expand All @@ -11847,19 +11837,21 @@ static void DiagnoseFailedEnableIfAttr(Sema &S, OverloadCandidate *Cand) {
}

static void DiagnoseFailedExplicitSpec(Sema &S, OverloadCandidate *Cand) {
ExplicitSpecifier ES = ExplicitSpecifier::getFromDecl(Cand->Function);
assert(Cand->Function && "Candidate must be a function");
FunctionDecl *Fn = Cand->Function;
ExplicitSpecifier ES = ExplicitSpecifier::getFromDecl(Fn);
assert(ES.isExplicit() && "not an explicit candidate");

unsigned Kind;
switch (Cand->Function->getDeclKind()) {
switch (Fn->getDeclKind()) {
case Decl::Kind::CXXConstructor:
Kind = 0;
break;
case Decl::Kind::CXXConversion:
Kind = 1;
break;
case Decl::Kind::CXXDeductionGuide:
Kind = Cand->Function->isImplicit() ? 0 : 2;
Kind = Fn->isImplicit() ? 0 : 2;
break;
default:
llvm_unreachable("invalid Decl");
Expand All @@ -11869,7 +11861,7 @@ static void DiagnoseFailedExplicitSpec(Sema &S, OverloadCandidate *Cand) {
// (particularly an out-of-class definition) will typically lack the
// 'explicit' specifier.
// FIXME: This is probably a good thing to do for all 'candidate' notes.
FunctionDecl *First = Cand->Function->getFirstDecl();
FunctionDecl *First = Fn->getFirstDecl();
if (FunctionDecl *Pattern = First->getTemplateInstantiationPattern())
First = Pattern->getFirstDecl();

Expand Down Expand Up @@ -11938,6 +11930,7 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand,
unsigned NumArgs,
bool TakingCandidateAddress,
LangAS CtorDestAS = LangAS::Default) {
assert(Cand->Function && "Candidate must be a function");
FunctionDecl *Fn = Cand->Function;
if (shouldSkipNotingLambdaConversionDecl(Fn))
return;
Expand All @@ -11952,8 +11945,7 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand,
// Skip implicit member functions when trying to resolve
// the address of a an overload set for a function pointer.
if (Cand->TookAddressOfOverload &&
!Cand->Function->hasCXXExplicitFunctionObjectParameter() &&
!Cand->Function->isStatic())
!Fn->hasCXXExplicitFunctionObjectParameter() && !Fn->isStatic())
return;

// Note deleted candidates, but only if they're viable.
Expand Down Expand Up @@ -12051,7 +12043,7 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand,
return;

case ovl_fail_addr_not_available: {
bool Available = checkAddressOfCandidateIsAvailable(S, Cand->Function);
bool Available = checkAddressOfCandidateIsAvailable(S, Fn);
(void)Available;
assert(!Available);
break;
Expand Down
1 change: 0 additions & 1 deletion clang/lib/Sema/SemaX86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,6 @@ bool SemaX86::CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
switch (BuiltinID) {
default:
return false;
case X86::BI__builtin_ia32_vec_ext_v2si:
case X86::BI__builtin_ia32_vec_ext_v2di:
case X86::BI__builtin_ia32_vextractf128_pd256:
case X86::BI__builtin_ia32_vextractf128_ps256:
Expand Down
364 changes: 236 additions & 128 deletions clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions clang/test/AST/Interp/cxx20.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -827,3 +827,17 @@ namespace CheckingNullPtrForInitialization {
return x;
}
}

namespace VariadicCallOperator {
class F {
public:
constexpr void operator()(int a, int b, ...) {}
};
constexpr int foo() {
F f;

f(1,2, 3);
return 1;
}
constexpr int A = foo();
}
12 changes: 12 additions & 0 deletions clang/test/AST/Interp/literals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1307,3 +1307,15 @@ namespace VolatileReads {
static_assert(b, ""); // both-error {{not an integral constant expression}} \
// both-note {{read of volatile-qualified type 'const volatile int' is not allowed in a constant expression}}
}
#if __cplusplus >= 201703L
namespace {
struct C {
int x;
};

template <const C *p> void f() {
const auto &[c] = *p;
&c; // both-warning {{expression result unused}}
}
}
#endif
19 changes: 19 additions & 0 deletions clang/test/AST/Interp/records.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1537,3 +1537,22 @@ namespace BitSet {
Bitset()
};
}

namespace ArrayInitChain {
struct StringLiteral {
const char *S;
};

struct CustomOperandVal {
StringLiteral Str;
unsigned Width;
unsigned Mask = Width + 1;
};

constexpr CustomOperandVal A[] = {
{},
};
static_assert(A[0].Str.S == nullptr, "");
static_assert(A[0].Width == 0, "");
static_assert(A[0].Mask == 1, "");
}
5 changes: 5 additions & 0 deletions clang/test/AST/ast-dump-ptrauth-json.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -std=c++11 -ast-dump=json %s | FileCheck %s

// CHECK: "name": "__builtin_ptrauth_type_discriminator",

int d = __builtin_ptrauth_type_discriminator(int());
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,12 @@
</array>
<key>depth</key><integer>0</integer>
<key>extended_message</key>
<string>Memory allocated by malloc() should be deallocated by free(), not &apos;delete&apos;</string>
<string>Memory allocated by &apos;malloc()&apos; should be deallocated by &apos;free()&apos;, not &apos;delete&apos;</string>
<key>message</key>
<string>Memory allocated by malloc() should be deallocated by free(), not &apos;delete&apos;</string>
<string>Memory allocated by &apos;malloc()&apos; should be deallocated by &apos;free()&apos;, not &apos;delete&apos;</string>
</dict>
</array>
<key>description</key><string>Memory allocated by malloc() should be deallocated by free(), not &apos;delete&apos;</string>
<key>description</key><string>Memory allocated by &apos;malloc()&apos; should be deallocated by &apos;free()&apos;, not &apos;delete&apos;</string>
<key>category</key><string>Memory error</string>
<key>type</key><string>Bad deallocator</string>
<key>check_name</key><string>unix.MismatchedDeallocator</string>
Expand Down
10 changes: 5 additions & 5 deletions clang/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,20 @@ void testMallocUseAfterFree() {

void testMallocBadFree() {
int i;
free(&i); // expected-warning{{Argument to free() is the address of the local variable 'i', which is not memory allocated by malloc()}}
free(&i); // expected-warning{{Argument to 'free()' is the address of the local variable 'i', which is not memory allocated by 'malloc()'}}
}

void testMallocOffsetFree() {
int *p = (int *)malloc(sizeof(int));
free(++p); // expected-warning{{Argument to free() is offset by 4 bytes from the start of memory allocated by malloc()}}
free(++p); // expected-warning{{Argument to 'free()' is offset by 4 bytes from the start of memory allocated by 'malloc()'}}
}

//-----------------------------------------------------------------
// Check that unix.MismatchedDeallocator catches all types of bugs.
//-----------------------------------------------------------------
void testMismatchedDeallocator() {
int *x = (int *)malloc(sizeof(int));
delete x; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete'}}
delete x; // expected-warning{{Memory allocated by 'malloc()' should be deallocated by 'free()', not 'delete'}}
}

//----------------------------------------------------------------
Expand Down Expand Up @@ -69,7 +69,7 @@ void testNewBadFree() {

void testNewOffsetFree() {
int *p = new int;
operator delete(++p); // expected-warning{{Argument to operator delete is offset by 4 bytes from the start of memory allocated by 'new'}}
operator delete(++p); // expected-warning{{Argument to 'operator delete' is offset by 4 bytes from the start of memory allocated by 'new'}}
}

//----------------------------------------------------------------
Expand All @@ -88,7 +88,7 @@ void testMismatchedChangePtrThroughCall() {
void testMismatchedChangePointeeThroughCall() {
int *p = (int*)malloc(sizeof(int)*4);
changePointee(p);
delete p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete'}}
delete p; // expected-warning{{Memory allocated by 'malloc()' should be deallocated by 'free()', not 'delete'}}
}

void testShouldReportDoubleFreeNotMismatched() {
Expand Down
84 changes: 66 additions & 18 deletions clang/test/Analysis/MismatchedDeallocator-checker-test.mm
Original file line number Diff line number Diff line change
Expand Up @@ -14,86 +14,134 @@
void free(void *);
void __attribute((ownership_takes(malloc, 1))) my_free(void *);

void __attribute((ownership_returns(malloc1))) *my_malloc1(size_t);
void __attribute((ownership_takes(malloc1, 1))) my_free1(void *);

void __attribute((ownership_returns(malloc2))) *my_malloc2(size_t);

// The order of these declarations are important to verify that analisys still works even
// if there are less specific declarations of the same functions
void __attribute((ownership_returns(malloc3))) *my_malloc3(size_t);
void *my_malloc3(size_t);

void *my_malloc4(size_t);
void __attribute((ownership_returns(malloc4))) *my_malloc4(size_t);

//---------------------------------------------------------------
// Test if an allocation function matches deallocation function
//---------------------------------------------------------------

//--------------- test malloc family
void testMalloc1() {
int *p = (int *)malloc(sizeof(int));
delete p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete'}}
delete p; // expected-warning{{Memory allocated by 'malloc()' should be deallocated by 'free()', not 'delete'}}
}

void testMalloc2() {
int *p = (int *)malloc(8);
int *q = (int *)realloc(p, 16);
delete q; // expected-warning{{Memory allocated by realloc() should be deallocated by free(), not 'delete'}}
delete q; // expected-warning{{Memory allocated by 'realloc()' should be deallocated by 'free()', not 'delete'}}
}

void testMalloc3() {
int *p = (int *)calloc(1, sizeof(int));
delete p; // expected-warning{{Memory allocated by calloc() should be deallocated by free(), not 'delete'}}
delete p; // expected-warning{{Memory allocated by 'calloc()' should be deallocated by 'free()', not 'delete'}}
}

void testMalloc4(const char *s) {
char *p = strdup(s);
delete p; // expected-warning{{Memory allocated by strdup() should be deallocated by free(), not 'delete'}}
delete p; // expected-warning{{Memory allocated by 'strdup()' should be deallocated by 'free()', not 'delete'}}
}

void testMalloc5() {
int *p = (int *)my_malloc(sizeof(int));
delete p; // expected-warning{{Memory allocated by my_malloc() should be deallocated by free(), not 'delete'}}
delete p; // expected-warning{{Memory allocated by 'my_malloc()' should be deallocated by 'free()', not 'delete'}}
}

void testMalloc6() {
int *p = (int *)malloc(sizeof(int));
operator delete(p); // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not operator delete}}
operator delete(p); // expected-warning{{Memory allocated by 'malloc()' should be deallocated by 'free()', not 'operator delete'}}
}

void testMalloc7() {
int *p = (int *)malloc(sizeof(int));
delete[] p; // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not 'delete[]'}}
delete[] p; // expected-warning{{Memory allocated by 'malloc()' should be deallocated by 'free()', not 'delete[]'}}
}

void testMalloc8() {
int *p = (int *)malloc(sizeof(int));
operator delete[](p); // expected-warning{{Memory allocated by malloc() should be deallocated by free(), not operator delete[]}}
operator delete[](p); // expected-warning{{Memory allocated by 'malloc()' should be deallocated by 'free()', not 'operator delete[]'}}
}

void testMalloc9() {
int *p = (int *)my_malloc(sizeof(int));
my_free(p); // no warning
}

void testMalloc10() {
int *p = (int *)my_malloc1(sizeof(int));
my_free1(p); // no warning
}

void testMalloc11() {
int *p = (int *)my_malloc1(sizeof(int));
my_free(p); // expected-warning{{Memory allocated by 'my_malloc1()' should be deallocated by function that takes ownership of 'malloc1', not 'my_free()', which takes ownership of 'malloc'}}
}

void testMalloc12() {
int *p = (int *)my_malloc2(sizeof(int));
my_free1(p); // expected-warning{{Memory allocated by 'my_malloc2()' should be deallocated by function that takes ownership of 'malloc2', not 'my_free1()', which takes ownership of 'malloc1'}}
}

void testMalloc13() {
int *p = (int *)my_malloc1(sizeof(int));
free(p); // expected-warning{{Memory allocated by 'my_malloc1()' should be deallocated by function that takes ownership of 'malloc1', not 'free()'}}
}

void testMalloc14() {
int *p = (int *)my_malloc3(sizeof(int));
free(p); // expected-warning{{Memory allocated by 'my_malloc3()' should be deallocated by function that takes ownership of 'malloc3', not 'free()'}}
}

void testMalloc15() {
int *p = (int *)my_malloc4(sizeof(int));
free(p); // expected-warning{{Memory allocated by 'my_malloc4()' should be deallocated by function that takes ownership of 'malloc4', not 'free()'}}
}

void testAlloca() {
int *p = (int *)__builtin_alloca(sizeof(int));
delete p; // expected-warning{{Memory allocated by alloca() should not be deallocated}}
delete p; // expected-warning{{Memory allocated by 'alloca()' should not be deallocated}}
}

//--------------- test new family
void testNew1() {
int *p = new int;
free(p); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not free()}}
free(p); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not 'free()'}}
}

void testNew2() {
int *p = (int *)operator new(0);
free(p); // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not free()}}
free(p); // expected-warning{{Memory allocated by 'operator new' should be deallocated by 'delete', not 'free()'}}
}

void testNew3() {
int *p = new int[1];
free(p); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not free()}}
free(p); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'free()'}}
}

void testNew4() {
int *p = new int;
realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not realloc()}}
realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new' should be deallocated by 'delete', not 'realloc()'}}
}

void testNew5() {
int *p = (int *)operator new(0);
realloc(p, sizeof(long)); // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not realloc()}}
realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'operator new' should be deallocated by 'delete', not 'realloc()'}}
}

void testNew6() {
int *p = new int[1];
realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not realloc()}}
realloc(p, sizeof(long)); // expected-warning{{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'realloc()'}}
}

int *allocInt() {
Expand All @@ -106,7 +154,7 @@ void testNew7() {

void testNew8() {
int *p = (int *)operator new(0);
delete[] p; // expected-warning{{Memory allocated by operator new should be deallocated by 'delete', not 'delete[]'}}
delete[] p; // expected-warning{{Memory allocated by 'operator new' should be deallocated by 'delete', not 'delete[]'}}
}

int *allocIntArray(unsigned c) {
Expand All @@ -120,7 +168,7 @@ void testNew9() {

void testNew10() {
int *p = (int *)operator new[](0);
delete p; // expected-warning{{Memory allocated by operator new[] should be deallocated by 'delete[]', not 'delete'}}
delete p; // expected-warning{{Memory allocated by 'operator new[]' should be deallocated by 'delete[]', not 'delete'}}
}

void testNew11(NSUInteger dataLength) {
Expand Down Expand Up @@ -208,7 +256,7 @@ explicit SimpleSmartPointer(T *p = 0) : ptr(p) {}
~SimpleSmartPointer() {
delete ptr;
// expected-warning@-1 {{Memory allocated by 'new[]' should be deallocated by 'delete[]', not 'delete'}}
// expected-warning@-2 {{Memory allocated by malloc() should be deallocated by free(), not 'delete'}}
// expected-warning@-2 {{Memory allocated by 'malloc()' should be deallocated by 'free()', not 'delete'}}
}
};

Expand Down
6 changes: 3 additions & 3 deletions clang/test/Analysis/NewDelete-intersections.mm
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void testMallocFreeNoWarn() {
void testDeleteMalloced() {
int *p1 = (int *)malloc(sizeof(int));
delete p1;
// mismatch-warning@-1{{Memory allocated by malloc() should be deallocated by free(), not 'delete'}}
// mismatch-warning@-1{{Memory allocated by 'malloc()' should be deallocated by 'free()', not 'delete'}}

int *p2 = (int *)__builtin_alloca(sizeof(int));
delete p2; // no warn
Expand All @@ -59,13 +59,13 @@ void testUseZeroAllocatedMalloced() {
void testFreeOpNew() {
void *p = operator new(0);
free(p);
// mismatch-warning@-1{{Memory allocated by operator new should be deallocated by 'delete', not free()}}
// mismatch-warning@-1{{Memory allocated by 'operator new' should be deallocated by 'delete', not 'free()'}}
}

void testFreeNewExpr() {
int *p = new int;
free(p);
// mismatch-warning@-1{{Memory allocated by 'new' should be deallocated by 'delete', not free()}}
// mismatch-warning@-1{{Memory allocated by 'new' should be deallocated by 'delete', not 'free()'}}
free(p);
}

Expand Down
24 changes: 12 additions & 12 deletions clang/test/Analysis/free.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,21 @@ void *alloca(size_t);
void t1 (void) {
int a[] = { 1 };
free(a);
// expected-warning@-1{{Argument to free() is the address of the local variable 'a', which is not memory allocated by malloc()}}
// expected-warning@-1{{Argument to 'free()' is the address of the local variable 'a', which is not memory allocated by 'malloc()'}}
// expected-warning@-2{{attempt to call free on non-heap object 'a'}}
}

void t2 (void) {
int a = 1;
free(&a);
// expected-warning@-1{{Argument to free() is the address of the local variable 'a', which is not memory allocated by malloc()}}
// expected-warning@-1{{Argument to 'free()' is the address of the local variable 'a', which is not memory allocated by 'malloc()'}}
// expected-warning@-2{{attempt to call free on non-heap object 'a'}}
}

void t3 (void) {
static int a[] = { 1 };
free(a);
// expected-warning@-1{{Argument to free() is the address of the static variable 'a', which is not memory allocated by malloc()}}
// expected-warning@-1{{Argument to 'free()' is the address of the static variable 'a', which is not memory allocated by 'malloc()'}}
// expected-warning@-2{{attempt to call free on non-heap object 'a'}}
}

Expand All @@ -42,7 +42,7 @@ void t5 (void) {

void t6 (void) {
free((void*)1000);
// expected-warning@-1{{Argument to free() is a constant address (1000), which is not memory allocated by malloc()}}
// expected-warning@-1{{Argument to 'free()' is a constant address (1000), which is not memory allocated by 'malloc()'}}
// expected-warning@-2{{attempt to call free on non-heap object '(void *)1000'}}
}

Expand All @@ -58,42 +58,42 @@ void t8 (char **x) {
void t9 (void) {
label:
free(&&label);
// expected-warning@-1{{Argument to free() is the address of the label 'label', which is not memory allocated by malloc()}}
// expected-warning@-1{{Argument to 'free()' is the address of the label 'label', which is not memory allocated by 'malloc()'}}
// expected-warning@-2{{attempt to call free on non-heap object 'label'}}
}

void t10 (void) {
free((void*)&t10);
// expected-warning@-1{{Argument to free() is the address of the function 't10', which is not memory allocated by malloc()}}
// expected-warning@-1{{Argument to 'free()' is the address of the function 't10', which is not memory allocated by 'malloc()'}}
// expected-warning@-2{{attempt to call free on non-heap object 't10'}}
}

void t11 (void) {
char *p = (char*)alloca(2);
free(p); // expected-warning {{Memory allocated by alloca() should not be deallocated}}
free(p); // expected-warning {{Memory allocated by 'alloca()' should not be deallocated}}
}

void t12 (void) {
char *p = (char*)__builtin_alloca(2);
free(p); // expected-warning {{Memory allocated by alloca() should not be deallocated}}
free(p); // expected-warning {{Memory allocated by 'alloca()' should not be deallocated}}
}

void t13 (void) {
free(^{return;});
// expected-warning@-1{{Argument to free() is a block, which is not memory allocated by malloc()}}
// expected-warning@-1{{Argument to 'free()' is a block, which is not memory allocated by 'malloc()'}}
// expected-warning@-2{{attempt to call free on non-heap object: block expression}}
}

void t14 (char a) {
free(&a);
// expected-warning@-1{{Argument to free() is the address of the parameter 'a', which is not memory allocated by malloc()}}
// expected-warning@-1{{Argument to 'free()' is the address of the parameter 'a', which is not memory allocated by 'malloc()'}}
// expected-warning@-2{{attempt to call free on non-heap object 'a'}}
}

static int someGlobal[2];
void t15 (void) {
free(someGlobal);
// expected-warning@-1{{Argument to free() is the address of the global variable 'someGlobal', which is not memory allocated by malloc()}}
// expected-warning@-1{{Argument to 'free()' is the address of the global variable 'someGlobal', which is not memory allocated by 'malloc()'}}
// expected-warning@-2{{attempt to call free on non-heap object 'someGlobal'}}
}

Expand All @@ -105,7 +105,7 @@ void t16 (char **x, int offset) {
int *iptr(void);
void t17(void) {
free(iptr); // Oops, forgot to call iptr().
// expected-warning@-1{{Argument to free() is the address of the function 'iptr', which is not memory allocated by malloc()}}
// expected-warning@-1{{Argument to 'free()' is the address of the function 'iptr', which is not memory allocated by 'malloc()'}}
// expected-warning@-2{{attempt to call free on non-heap object 'iptr'}}
}

Expand Down
Loading