45 changes: 45 additions & 0 deletions clang/include/clang/Basic/StackExhaustionHandler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//===--- StackExhaustionHandler.h - A utility for warning once when close to out
// of stack space -------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// Defines a utilitiy for warning once when close to out of stack space.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_BASIC_STACK_EXHAUSTION_HANDLER_H
#define LLVM_CLANG_BASIC_STACK_EXHAUSTION_HANDLER_H

#include "clang/Basic/Diagnostic.h"

namespace clang {
class StackExhaustionHandler {
public:
StackExhaustionHandler(DiagnosticsEngine &diags) : DiagsRef(diags) {}

/// Run some code with "sufficient" stack space. (Currently, at least 256K
/// is guaranteed). Produces a warning if we're low on stack space and
/// allocates more in that case. Use this in code that may recurse deeply to
/// avoid stack overflow.
void runWithSufficientStackSpace(SourceLocation Loc,
llvm::function_ref<void()> Fn);

/// Check to see if we're low on stack space and produce a warning if we're
/// low on stack space (Currently, at least 256Kis guaranteed).
void warnOnStackNearlyExhausted(SourceLocation Loc);

private:
/// Warn that the stack is nearly exhausted.
void warnStackExhausted(SourceLocation Loc);

DiagnosticsEngine &DiagsRef;
bool WarnedStackExhausted = false;
};
} // end namespace clang

#endif // LLVM_CLANG_BASIC_STACK_EXHAUSTION_HANDLER_H
11 changes: 7 additions & 4 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -3454,7 +3454,8 @@ def fno_strict_aliasing : Flag<["-"], "fno-strict-aliasing">, Group<f_Group>,
def fstruct_path_tbaa : Flag<["-"], "fstruct-path-tbaa">, Group<f_Group>;
def fno_struct_path_tbaa : Flag<["-"], "fno-struct-path-tbaa">, Group<f_Group>;
def fno_strict_enums : Flag<["-"], "fno-strict-enums">, Group<f_Group>;
def fno_strict_overflow : Flag<["-"], "fno-strict-overflow">, Group<f_Group>;
def fno_strict_overflow : Flag<["-"], "fno-strict-overflow">, Group<f_Group>,
Visibility<[ClangOption, FlangOption]>;
def fno_pointer_tbaa : Flag<["-"], "fno-pointer-tbaa">, Group<f_Group>;
def fno_temp_file : Flag<["-"], "fno-temp-file">, Group<f_Group>,
Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>, HelpText<
Expand All @@ -3470,7 +3471,8 @@ def fno_verbose_asm : Flag<["-"], "fno-verbose-asm">, Group<f_Group>,
Visibility<[ClangOption, CC1Option]>,
MarshallingInfoNegativeFlag<CodeGenOpts<"AsmVerbose">>;
def fno_working_directory : Flag<["-"], "fno-working-directory">, Group<f_Group>;
def fno_wrapv : Flag<["-"], "fno-wrapv">, Group<f_Group>;
def fno_wrapv : Flag<["-"], "fno-wrapv">, Group<f_Group>,
Visibility<[ClangOption, FlangOption]>;
def fobjc_arc : Flag<["-"], "fobjc-arc">, Group<f_Group>,
Visibility<[ClangOption, CC1Option]>,
HelpText<"Synthesize retain and release calls for Objective-C pointers">;
Expand Down Expand Up @@ -3966,7 +3968,8 @@ defm strict_vtable_pointers : BoolFOption<"strict-vtable-pointers",
"Enable optimizations based on the strict rules for"
" overwriting polymorphic C++ objects">,
NegFlag<SetFalse>>;
def fstrict_overflow : Flag<["-"], "fstrict-overflow">, Group<f_Group>;
def fstrict_overflow : Flag<["-"], "fstrict-overflow">, Group<f_Group>,
Visibility<[ClangOption, FlangOption]>;
def fpointer_tbaa : Flag<["-"], "fpointer-tbaa">, Group<f_Group>;
def fdriver_only : Flag<["-"], "fdriver-only">, Flags<[NoXarchOption]>,
Visibility<[ClangOption, CLOption, DXCOption]>,
Expand Down Expand Up @@ -4235,7 +4238,7 @@ defm virtual_function_elimination : BoolFOption<"virtual-function-elimination",
NegFlag<SetFalse>, BothFlags<[], [ClangOption, CLOption]>>;

def fwrapv : Flag<["-"], "fwrapv">, Group<f_Group>,
Visibility<[ClangOption, CC1Option]>,
Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
HelpText<"Treat signed integer overflow as two's complement">;
def fwritable_strings : Flag<["-"], "fwritable-strings">, Group<f_Group>,
Visibility<[ClangOption, CC1Option]>,
Expand Down
25 changes: 25 additions & 0 deletions clang/include/clang/Format/Format.h
Original file line number Diff line number Diff line change
Expand Up @@ -3938,6 +3938,29 @@ struct FormatStyle {
/// \version 14
bool RemoveBracesLLVM;

/// Remove empty lines within unwrapped lines.
/// \code
/// false: true:
///
/// int c vs. int c = a + b;
///
/// = a + b;
///
/// enum : unsigned vs. enum : unsigned {
/// AA = 0,
/// { BB
/// AA = 0, } myEnum;
/// BB
/// } myEnum;
///
/// while ( vs. while (true) {
/// }
/// true) {
/// }
/// \endcode
/// \version 20
bool RemoveEmptyLinesInUnwrappedLines;

/// Types of redundant parentheses to remove.
enum RemoveParenthesesStyle : int8_t {
/// Do not remove parentheses.
Expand Down Expand Up @@ -5232,6 +5255,8 @@ struct FormatStyle {
RawStringFormats == R.RawStringFormats &&
ReferenceAlignment == R.ReferenceAlignment &&
RemoveBracesLLVM == R.RemoveBracesLLVM &&
RemoveEmptyLinesInUnwrappedLines ==
R.RemoveEmptyLinesInUnwrappedLines &&
RemoveParentheses == R.RemoveParentheses &&
RemoveSemicolon == R.RemoveSemicolon &&
RequiresClausePosition == R.RequiresClausePosition &&
Expand Down
6 changes: 2 additions & 4 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include "clang/Basic/PragmaKinds.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/StackExhaustionHandler.h"
#include "clang/Basic/TemplateKinds.h"
#include "clang/Basic/TokenKinds.h"
#include "clang/Basic/TypeTraits.h"
Expand Down Expand Up @@ -546,9 +547,6 @@ class Sema final : public SemaBase {
/// Print out statistics about the semantic analysis.
void PrintStats() const;

/// Warn that the stack is nearly exhausted.
void warnStackExhausted(SourceLocation Loc);

/// Run some code with "sufficient" stack space. (Currently, at least 256K is
/// guaranteed). Produces a warning if we're low on stack space and allocates
/// more in that case. Use this in code that may recurse deeply (for example,
Expand Down Expand Up @@ -1183,7 +1181,7 @@ class Sema final : public SemaBase {
std::optional<std::unique_ptr<DarwinSDKInfo>> CachedDarwinSDKInfo;
bool WarnedDarwinSDKInfoMissing = false;

bool WarnedStackExhausted = false;
StackExhaustionHandler StackHandler;

Sema(const Sema &) = delete;
void operator=(const Sema &) = delete;
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -1149,7 +1149,7 @@ enum PredefinedTypeIDs {
///
/// Type IDs for non-predefined types will start at
/// NUM_PREDEF_TYPE_IDs.
const unsigned NUM_PREDEF_TYPE_IDS = 506;
const unsigned NUM_PREDEF_TYPE_IDS = 509;

// Ensure we do not overrun the predefined types we reserved
// in the enum PredefinedTypeIDs above.
Expand Down
6 changes: 4 additions & 2 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/OpenCLOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/StackExhaustionHandler.h"
#include "clang/Basic/Version.h"
#include "clang/Lex/ExternalPreprocessorSource.h"
#include "clang/Lex/HeaderSearch.h"
Expand Down Expand Up @@ -445,7 +446,7 @@ class ASTReader
DiagnosticsEngine &Diags;
// Sema has duplicate logic, but SemaObj can sometimes be null so ASTReader
// has its own version.
bool WarnedStackExhausted = false;
StackExhaustionHandler StackHandler;

/// The semantic analysis object that will be processing the
/// AST files and the translation unit that uses it.
Expand Down Expand Up @@ -2180,7 +2181,8 @@ class ASTReader
/// Report a diagnostic.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const;

void warnStackExhausted(SourceLocation Loc);
void runWithSufficientStackSpace(SourceLocation Loc,
llvm::function_ref<void()> Fn);

IdentifierInfo *DecodeIdentifierInfo(serialization::IdentifierID ID);

Expand Down
26 changes: 13 additions & 13 deletions clang/lib/AST/ASTImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,24 +362,24 @@ namespace clang {
template <typename TemplateParmDeclT>
Error importTemplateParameterDefaultArgument(const TemplateParmDeclT *D,
TemplateParmDeclT *ToD) {
Error Err = Error::success();
if (D->hasDefaultArgument()) {
if (D->defaultArgumentWasInherited()) {
auto *ToInheritedFrom = const_cast<TemplateParmDeclT *>(
importChecked(Err, D->getDefaultArgStorage().getInheritedFrom()));
if (Err)
return Err;
Expected<TemplateParmDeclT *> ToInheritedFromOrErr =
import(D->getDefaultArgStorage().getInheritedFrom());
if (!ToInheritedFromOrErr)
return ToInheritedFromOrErr.takeError();
TemplateParmDeclT *ToInheritedFrom = *ToInheritedFromOrErr;
if (!ToInheritedFrom->hasDefaultArgument()) {
// Resolve possible circular dependency between default value of the
// template argument and the template declaration.
const auto ToInheritedDefaultArg =
importChecked(Err, D->getDefaultArgStorage()
.getInheritedFrom()
->getDefaultArgument());
if (Err)
return Err;
Expected<TemplateArgumentLoc> ToInheritedDefaultArgOrErr =
import(D->getDefaultArgStorage()
.getInheritedFrom()
->getDefaultArgument());
if (!ToInheritedDefaultArgOrErr)
return ToInheritedDefaultArgOrErr.takeError();
ToInheritedFrom->setDefaultArgument(Importer.getToContext(),
ToInheritedDefaultArg);
*ToInheritedDefaultArgOrErr);
}
ToD->setInheritedDefaultArgument(ToD->getASTContext(),
ToInheritedFrom);
Expand All @@ -395,7 +395,7 @@ namespace clang {
*ToDefaultArgOrErr);
}
}
return Err;
return Error::success();
}

public:
Expand Down
22 changes: 16 additions & 6 deletions clang/lib/AST/ByteCode/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4132,10 +4132,16 @@ template <class Emitter>
bool Compiler<Emitter>::visitExpr(const Expr *E, bool DestroyToplevelScope) {
LocalScope<Emitter> RootScope(this);

// If we won't destroy the toplevel scope, check for memory leaks first.
if (!DestroyToplevelScope) {
if (!this->emitCheckAllocations(E))
return false;
}

auto maybeDestroyLocals = [&]() -> bool {
if (DestroyToplevelScope)
return RootScope.destroyLocals();
return true;
return RootScope.destroyLocals() && this->emitCheckAllocations(E);
return this->emitCheckAllocations(E);
};

// Void expressions.
Expand Down Expand Up @@ -4171,8 +4177,7 @@ bool Compiler<Emitter>::visitExpr(const Expr *E, bool DestroyToplevelScope) {
return this->emitRetValue(E) && maybeDestroyLocals();
}

(void)maybeDestroyLocals();
return false;
return maybeDestroyLocals() && this->emitCheckAllocations(E) && false;
}

template <class Emitter>
Expand Down Expand Up @@ -4214,7 +4219,8 @@ bool Compiler<Emitter>::visitDeclAndReturn(const VarDecl *VD,
DeclScope<Emitter> LS(this, VD);
if (!this->visit(VD->getAnyInitializer()))
return false;
return this->emitRet(VarT.value_or(PT_Ptr), VD) && LS.destroyLocals();
return this->emitRet(VarT.value_or(PT_Ptr), VD) && LS.destroyLocals() &&
this->emitCheckAllocations(VD);
}

LocalScope<Emitter> VDScope(this, VD);
Expand Down Expand Up @@ -4260,7 +4266,7 @@ bool Compiler<Emitter>::visitDeclAndReturn(const VarDecl *VD,
return false;
}

return VDScope.destroyLocals();
return VDScope.destroyLocals() && this->emitCheckAllocations(VD);
}

template <class Emitter>
Expand Down Expand Up @@ -4535,6 +4541,10 @@ bool Compiler<Emitter>::VisitCallExpr(const CallExpr *E) {
return VisitBuiltinCallExpr(E, Builtin::BI__builtin_operator_delete);
}
}
// Explicit calls to trivial destructors
if (const auto *DD = dyn_cast_if_present<CXXDestructorDecl>(FuncDecl);
DD && DD->isTrivial())
return true;

QualType ReturnType = E->getCallReturnType(Ctx.getASTContext());
std::optional<PrimType> T = classify(ReturnType);
Expand Down
3 changes: 1 addition & 2 deletions clang/lib/AST/ByteCode/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,7 @@ bool Context::evaluate(State &Parent, const Expr *E, APValue &Result,
Compiler<EvalEmitter> C(*this, *P, Parent, Stk);

auto Res = C.interpretExpr(E, /*ConvertResultToRValue=*/false,
/*DestroyToplevelScope=*/Kind ==
ConstantExprKind::ClassTemplateArgument);
/*DestroyToplevelScope=*/true);
if (Res.isInvalid()) {
C.cleanup();
Stk.clearTo(StackSizeBefore);
Expand Down
17 changes: 0 additions & 17 deletions clang/lib/AST/ByteCode/EvalEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,17 +132,10 @@ bool EvalEmitter::fallthrough(const LabelTy &Label) {
return true;
}

static bool checkReturnState(InterpState &S) {
return S.maybeDiagnoseDanglingAllocations();
}

template <PrimType OpType> bool EvalEmitter::emitRet(const SourceInfo &Info) {
if (!isActive())
return true;

if (!checkReturnState(S))
return false;

using T = typename PrimConv<OpType>::T;
EvalResult.setValue(S.Stk.pop<T>().toAPValue(Ctx.getASTContext()));
return true;
Expand All @@ -159,9 +152,6 @@ template <> bool EvalEmitter::emitRet<PT_Ptr>(const SourceInfo &Info) {
if (CheckFullyInitialized && !EvalResult.checkFullyInitialized(S, Ptr))
return false;

if (!checkReturnState(S))
return false;

// Implicitly convert lvalue to rvalue, if requested.
if (ConvertResultToRValue) {
if (!Ptr.isZero() && !Ptr.isDereferencable())
Expand Down Expand Up @@ -194,16 +184,12 @@ template <> bool EvalEmitter::emitRet<PT_FnPtr>(const SourceInfo &Info) {
if (!isActive())
return true;

if (!checkReturnState(S))
return false;
// Function pointers cannot be converted to rvalues.
EvalResult.setFunctionPointer(S.Stk.pop<FunctionPointer>());
return true;
}

bool EvalEmitter::emitRetVoid(const SourceInfo &Info) {
if (!checkReturnState(S))
return false;
EvalResult.setValid();
return true;
}
Expand All @@ -216,9 +202,6 @@ bool EvalEmitter::emitRetValue(const SourceInfo &Info) {
if (CheckFullyInitialized && !EvalResult.checkFullyInitialized(S, Ptr))
return false;

if (!checkReturnState(S))
return false;

if (std::optional<APValue> APV =
Ptr.toRValue(S.getASTContext(), EvalResult.getSourceType())) {
EvalResult.setValue(*APV);
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/AST/ByteCode/Interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -1841,6 +1841,7 @@ bool Init(InterpState &S, CodePtr OpPC) {
assert(false);
return false;
}
Ptr.activate();
Ptr.initialize();
new (&Ptr.deref<T>()) T(Value);
return true;
Expand All @@ -1852,6 +1853,7 @@ bool InitPop(InterpState &S, CodePtr OpPC) {
const Pointer &Ptr = S.Stk.pop<Pointer>();
if (!CheckInit(S, OpPC, Ptr))
return false;
Ptr.activate();
Ptr.initialize();
new (&Ptr.deref<T>()) T(Value);
return true;
Expand Down Expand Up @@ -3005,6 +3007,10 @@ static inline bool IsConstantContext(InterpState &S, CodePtr OpPC) {
return true;
}

static inline bool CheckAllocations(InterpState &S, CodePtr OpPC) {
return S.maybeDiagnoseDanglingAllocations();
}

/// Check if the initializer and storage types of a placement-new expression
/// match.
bool CheckNewTypeMismatch(InterpState &S, CodePtr OpPC, const Expr *E,
Expand Down
21 changes: 21 additions & 0 deletions clang/lib/AST/ByteCode/InterpBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,20 @@ static bool interp__builtin_fabs(InterpState &S, CodePtr OpPC,
return true;
}

static bool interp__builtin_abs(InterpState &S, CodePtr OpPC,
const InterpFrame *Frame, const Function *Func,
const CallExpr *Call) {
PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
APSInt Val = peekToAPSInt(S.Stk, ArgT);
if (Val ==
APSInt(APInt::getSignedMinValue(Val.getBitWidth()), /*IsUnsigned=*/false))
return false;
if (Val.isNegative())
Val.negate();
pushInteger(S, Val, Call->getType());
return true;
}

static bool interp__builtin_popcount(InterpState &S, CodePtr OpPC,
const InterpFrame *Frame,
const Function *Func,
Expand Down Expand Up @@ -1808,6 +1822,13 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
return false;
break;

case Builtin::BI__builtin_abs:
case Builtin::BI__builtin_labs:
case Builtin::BI__builtin_llabs:
if (!interp__builtin_abs(S, OpPC, Frame, F, Call))
return false;
break;

case Builtin::BI__builtin_popcount:
case Builtin::BI__builtin_popcountl:
case Builtin::BI__builtin_popcountll:
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/ByteCode/Opcodes.td
Original file line number Diff line number Diff line change
Expand Up @@ -836,3 +836,4 @@ def CheckNewTypeMismatchArray : Opcode {
}

def IsConstantContext: Opcode;
def CheckAllocations : Opcode;
10 changes: 7 additions & 3 deletions clang/lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2512,7 +2512,8 @@ bool VarDecl::isUsableInConstantExpressions(const ASTContext &Context) const {
if (!DefVD->mightBeUsableInConstantExpressions(Context))
return false;
// ... and its initializer is a constant initializer.
if (Context.getLangOpts().CPlusPlus && !DefVD->hasConstantInitialization())
if ((Context.getLangOpts().CPlusPlus || getLangOpts().C23) &&
!DefVD->hasConstantInitialization())
return false;
// C++98 [expr.const]p1:
// An integral constant-expression can involve only [...] const variables
Expand Down Expand Up @@ -2619,8 +2620,11 @@ bool VarDecl::hasICEInitializer(const ASTContext &Context) const {
}

bool VarDecl::hasConstantInitialization() const {
// In C, all globals (and only globals) have constant initialization.
if (hasGlobalStorage() && !getASTContext().getLangOpts().CPlusPlus)
// In C, all globals and constexpr variables should have constant
// initialization. For constexpr variables in C check that initializer is a
// constant initializer because they can be used in constant expressions.
if (hasGlobalStorage() && !getASTContext().getLangOpts().CPlusPlus &&
!isConstexpr())
return true;

// In C++, it depends on whether the evaluation at the point of definition
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/Expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1989,7 +1989,7 @@ Expr *CastExpr::getSubExprAsWritten() {
SubExpr = IgnoreExprNodes(cast<CXXConstructExpr>(SubExpr)->getArg(0),
ignoreImplicitSemaNodes);
} else if (E->getCastKind() == CK_UserDefinedConversion) {
assert((isa<CXXMemberCallExpr>(SubExpr) || isa<BlockExpr>(SubExpr)) &&
assert((isa<CallExpr, BlockExpr>(SubExpr)) &&
"Unexpected SubExpr for CK_UserDefinedConversion.");
if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SubExpr))
SubExpr = MCE->getImplicitObjectArgument();
Expand Down
14 changes: 14 additions & 0 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13098,6 +13098,20 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
return Success(Val.popcount() % 2, E);
}

case Builtin::BI__builtin_abs:
case Builtin::BI__builtin_labs:
case Builtin::BI__builtin_llabs: {
APSInt Val;
if (!EvaluateInteger(E->getArg(0), Val, Info))
return false;
if (Val == APSInt(APInt::getSignedMinValue(Val.getBitWidth()),
/*IsUnsigned=*/false))
return false;
if (Val.isNegative())
Val.negate();
return Success(Val, E);
}

case Builtin::BI__builtin_popcount:
case Builtin::BI__builtin_popcountl:
case Builtin::BI__builtin_popcountll:
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Basic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ add_clang_library(clangBasic
SourceManager.cpp
SourceMgrAdapter.cpp
Stack.cpp
StackExhaustionHandler.cpp
TargetID.cpp
TargetInfo.cpp
Targets.cpp
Expand Down
35 changes: 35 additions & 0 deletions clang/lib/Basic/StackExhaustionHandler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//===--- StackExhaustionHandler.cpp - - A utility for warning once when close
// to out of stack space -------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// Defines a utilitiy for warning once when close to out of stack space.
///
//===----------------------------------------------------------------------===//

#include "clang/Basic/StackExhaustionHandler.h"
#include "clang/Basic/Stack.h"

void clang::StackExhaustionHandler::runWithSufficientStackSpace(
SourceLocation Loc, llvm::function_ref<void()> Fn) {
clang::runWithSufficientStackSpace([&] { warnStackExhausted(Loc); }, Fn);
}

void clang::StackExhaustionHandler::warnOnStackNearlyExhausted(
SourceLocation Loc) {
if (isStackNearlyExhausted())
warnStackExhausted(Loc);
}

void clang::StackExhaustionHandler::warnStackExhausted(SourceLocation Loc) {
// Only warn about this once.
if (!WarnedStackExhausted) {
DiagsRef.Report(Loc, diag::warn_stack_exhausted);
WarnedStackExhausted = true;
}
}
10 changes: 10 additions & 0 deletions clang/lib/Basic/Targets/RISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ bool RISCVTargetInfo::validateAsmConstraint(
case 'S': // A symbol or label reference with a constant offset
Info.setAllowsRegister();
return true;
case 'c':
// A RVC register - GPR or FPR
if (Name[1] == 'r' || Name[1] == 'f') {
Info.setAllowsRegister();
Name += 1;
return true;
}
return false;
case 'v':
// A vector register.
if (Name[1] == 'r' || Name[1] == 'd' || Name[1] == 'm') {
Expand All @@ -114,6 +122,8 @@ bool RISCVTargetInfo::validateAsmConstraint(
std::string RISCVTargetInfo::convertConstraint(const char *&Constraint) const {
std::string R;
switch (*Constraint) {
// c* and v* are two-letter constraints on RISC-V.
case 'c':
case 'v':
R = std::string("^") + std::string(Constraint, 2);
Constraint += 1;
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5636,10 +5636,10 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
llvm::Type *ArgTys[] = {Arg0->getType(), I8PTy, Int32Ty, Int32Ty};
llvm::FunctionType *FTy = llvm::FunctionType::get(
Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
Value *BCast = Builder.CreatePointerCast(Arg1, I8PTy);
Value *ACast = Builder.CreateAddrSpaceCast(Arg1, I8PTy);
return RValue::get(
EmitRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name),
{Arg0, BCast, PacketSize, PacketAlign}));
{Arg0, ACast, PacketSize, PacketAlign}));
} else {
assert(4 == E->getNumArgs() &&
"Illegal number of parameters to pipe function");
Expand Down
12 changes: 2 additions & 10 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ CodeGenModule::CodeGenModule(ASTContext &C,
: Context(C), LangOpts(C.getLangOpts()), FS(FS), HeaderSearchOpts(HSO),
PreprocessorOpts(PPO), CodeGenOpts(CGO), TheModule(M), Diags(diags),
Target(C.getTargetInfo()), ABI(createCXXABI(*this)),
VMContext(M.getContext()), VTables(*this),
VMContext(M.getContext()), VTables(*this), StackHandler(diags),
SanitizerMD(new SanitizerMetadata(*this)) {

// Initialize the type cache.
Expand Down Expand Up @@ -1595,17 +1595,9 @@ void CodeGenModule::ErrorUnsupported(const Decl *D, const char *Type) {
getDiags().Report(Context.getFullLoc(D->getLocation()), DiagID) << Msg;
}

void CodeGenModule::warnStackExhausted(SourceLocation Loc) {
// Only warn about this once.
if (!WarnedStackExhausted) {
getDiags().Report(Loc, diag::warn_stack_exhausted);
WarnedStackExhausted = true;
}
}

void CodeGenModule::runWithSufficientStackSpace(SourceLocation Loc,
llvm::function_ref<void()> Fn) {
clang::runWithSufficientStackSpace([&] { warnStackExhausted(Loc); }, Fn);
StackHandler.runWithSufficientStackSpace(Loc, Fn);
}

llvm::ConstantInt *CodeGenModule::getSize(CharUnits size) {
Expand Down
6 changes: 2 additions & 4 deletions clang/lib/CodeGen/CodeGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/NoSanitizeList.h"
#include "clang/Basic/ProfileList.h"
#include "clang/Basic/StackExhaustionHandler.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/XRayLists.h"
#include "clang/Lex/PreprocessorOptions.h"
Expand Down Expand Up @@ -336,7 +337,7 @@ class CodeGenModule : public CodeGenTypeCache {
std::unique_ptr<llvm::IndexedInstrProfReader> PGOReader;
InstrProfStats PGOStats;
std::unique_ptr<llvm::SanitizerStatReport> SanStats;
bool WarnedStackExhausted = false;
StackExhaustionHandler StackHandler;

// A set of references that have only been seen via a weakref so far. This is
// used to remove the weak of the reference if we ever see a direct reference
Expand Down Expand Up @@ -1298,9 +1299,6 @@ class CodeGenModule : public CodeGenTypeCache {
/// Print out an error that codegen doesn't support the specified decl yet.
void ErrorUnsupported(const Decl *D, const char *Type);

/// Warn that the stack is nearly exhausted.
void warnStackExhausted(SourceLocation Loc);

/// Run some code with "sufficient" stack space. (Currently, at least 256K is
/// guaranteed). Produces a warning if we're low on stack space and allocates
/// more in that case. Use this in code that may recurse deeply to avoid stack
Expand Down
37 changes: 21 additions & 16 deletions clang/lib/CodeGen/ItaniumCXXABI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3437,7 +3437,7 @@ class ItaniumRTTIBuilder {
llvm::Constant *GetAddrOfExternalRTTIDescriptor(QualType Ty);

/// BuildVTablePointer - Build the vtable pointer for the given type.
void BuildVTablePointer(const Type *Ty);
void BuildVTablePointer(const Type *Ty, llvm::Constant *StorageAddress);

/// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
/// inheritance, according to the Itanium C++ ABI, 2.9.5p6b.
Expand Down Expand Up @@ -3834,7 +3834,8 @@ static bool CanUseSingleInheritance(const CXXRecordDecl *RD) {
return true;
}

void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty) {
void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty,
llvm::Constant *StorageAddress) {
// abi::__class_type_info.
static const char * const ClassTypeInfo =
"_ZTVN10__cxxabiv117__class_type_infoE";
Expand Down Expand Up @@ -3981,9 +3982,12 @@ void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty) {
VTable, Two);
}

if (auto &Schema = CGM.getCodeGenOpts().PointerAuth.CXXTypeInfoVTablePointer)
VTable = CGM.getConstantSignedPointer(VTable, Schema, nullptr, GlobalDecl(),
QualType(Ty, 0));
if (const auto &Schema =
CGM.getCodeGenOpts().PointerAuth.CXXTypeInfoVTablePointer)
VTable = CGM.getConstantSignedPointer(
VTable, Schema,
Schema.isAddressDiscriminated() ? StorageAddress : nullptr,
GlobalDecl(), QualType(Ty, 0));

Fields.push_back(VTable);
}
Expand Down Expand Up @@ -4099,8 +4103,18 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
llvm::GlobalVariable::LinkageTypes Linkage,
llvm::GlobalValue::VisibilityTypes Visibility,
llvm::GlobalValue::DLLStorageClassTypes DLLStorageClass) {
SmallString<256> Name;
llvm::raw_svector_ostream Out(Name);
CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);
llvm::Module &M = CGM.getModule();
llvm::GlobalVariable *OldGV = M.getNamedGlobal(Name);
// int8 is an arbitrary type to be replaced later with replaceInitializer.
llvm::GlobalVariable *GV =
new llvm::GlobalVariable(M, CGM.Int8Ty, /*isConstant=*/true, Linkage,
/*Initializer=*/nullptr, Name);

// Add the vtable pointer.
BuildVTablePointer(cast<Type>(Ty));
BuildVTablePointer(cast<Type>(Ty), GV);

// And the name.
llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage);
Expand Down Expand Up @@ -4218,16 +4232,7 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
llvm_unreachable("HLSL doesn't support RTTI");
}

llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields);

SmallString<256> Name;
llvm::raw_svector_ostream Out(Name);
CGM.getCXXABI().getMangleContext().mangleCXXRTTI(Ty, Out);
llvm::Module &M = CGM.getModule();
llvm::GlobalVariable *OldGV = M.getNamedGlobal(Name);
llvm::GlobalVariable *GV =
new llvm::GlobalVariable(M, Init->getType(),
/*isConstant=*/true, Linkage, Init, Name);
GV->replaceInitializer(llvm::ConstantStruct::getAnon(Fields));

// Export the typeinfo in the same circumstances as the vtable is exported.
auto GVDLLStorageClass = DLLStorageClass;
Expand Down
31 changes: 17 additions & 14 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3595,7 +3595,7 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
StringRef Value = A->getValue();
if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
!EffectiveTriple.isRISCV())
!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getAsString(Args) << TripleStr;
if ((EffectiveTriple.isX86() || EffectiveTriple.isARM() ||
Expand Down Expand Up @@ -3635,7 +3635,7 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
<< A->getOption().getName() << Value << "sysreg global";
return;
}
if (EffectiveTriple.isRISCV()) {
if (EffectiveTriple.isRISCV() || EffectiveTriple.isPPC()) {
if (Value != "tls" && Value != "global") {
D.Diag(diag::err_drv_invalid_value_with_suggestion)
<< A->getOption().getName() << Value << "tls global";
Expand All @@ -3656,7 +3656,7 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
StringRef Value = A->getValue();
if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
!EffectiveTriple.isARM() && !EffectiveTriple.isThumb() &&
!EffectiveTriple.isRISCV())
!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getAsString(Args) << TripleStr;
int Offset;
Expand All @@ -3676,7 +3676,7 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
if (Arg *A = Args.getLastArg(options::OPT_mstack_protector_guard_reg_EQ)) {
StringRef Value = A->getValue();
if (!EffectiveTriple.isX86() && !EffectiveTriple.isAArch64() &&
!EffectiveTriple.isRISCV())
!EffectiveTriple.isRISCV() && !EffectiveTriple.isPPC())
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< A->getAsString(Args) << TripleStr;
if (EffectiveTriple.isX86() && (Value != "fs" && Value != "gs")) {
Expand All @@ -3693,6 +3693,16 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
<< A->getOption().getName() << Value << "tp";
return;
}
if (EffectiveTriple.isPPC64() && Value != "r13") {
D.Diag(diag::err_drv_invalid_value_with_suggestion)
<< A->getOption().getName() << Value << "r13";
return;
}
if (EffectiveTriple.isPPC32() && Value != "r2") {
D.Diag(diag::err_drv_invalid_value_with_suggestion)
<< A->getOption().getName() << Value << "r2";
return;
}
A->render(Args, CmdArgs);
}

Expand Down Expand Up @@ -6914,16 +6924,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,

Args.AddLastArg(CmdArgs, options::OPT_ftrap_function_EQ);

// -fno-strict-overflow implies -fwrapv if it isn't disabled, but
// -fstrict-overflow won't turn off an explicitly enabled -fwrapv.
if (Arg *A = Args.getLastArg(options::OPT_fwrapv, options::OPT_fno_wrapv)) {
if (A->getOption().matches(options::OPT_fwrapv))
CmdArgs.push_back("-fwrapv");
} else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow,
options::OPT_fno_strict_overflow)) {
if (A->getOption().matches(options::OPT_fno_strict_overflow))
CmdArgs.push_back("-fwrapv");
}
// Handle -f[no-]wrapv and -f[no-]strict-overflow, which are used by both
// clang and flang.
renderCommonIntegerOverflowOptions(Args, CmdArgs);

Args.AddLastArg(CmdArgs, options::OPT_ffinite_loops,
options::OPT_fno_finite_loops);
Expand Down
14 changes: 14 additions & 0 deletions clang/lib/Driver/ToolChains/CommonArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3048,3 +3048,17 @@ bool tools::shouldRecordCommandLine(const ToolChain &TC,

return FRecordCommandLine || TC.UseDwarfDebugFlags() || GRecordCommandLine;
}

void tools::renderCommonIntegerOverflowOptions(const ArgList &Args,
ArgStringList &CmdArgs) {
// -fno-strict-overflow implies -fwrapv if it isn't disabled, but
// -fstrict-overflow won't turn off an explicitly enabled -fwrapv.
if (Arg *A = Args.getLastArg(options::OPT_fwrapv, options::OPT_fno_wrapv)) {
if (A->getOption().matches(options::OPT_fwrapv))
CmdArgs.push_back("-fwrapv");
} else if (Arg *A = Args.getLastArg(options::OPT_fstrict_overflow,
options::OPT_fno_strict_overflow)) {
if (A->getOption().matches(options::OPT_fno_strict_overflow))
CmdArgs.push_back("-fwrapv");
}
}
3 changes: 3 additions & 0 deletions clang/lib/Driver/ToolChains/CommonArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,9 @@ bool shouldRecordCommandLine(const ToolChain &TC,
bool &FRecordCommandLine,
bool &GRecordCommandLine);

void renderCommonIntegerOverflowOptions(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs);

} // end namespace tools
} // end namespace driver
} // end namespace clang
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Driver/ToolChains/Flang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -869,6 +869,8 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
}
}

renderCommonIntegerOverflowOptions(Args, CmdArgs);

assert((Output.isFilename() || Output.isNothing()) && "Invalid output.");
if (Output.isFilename()) {
CmdArgs.push_back("-o");
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Format/Format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1104,6 +1104,8 @@ template <> struct MappingTraits<FormatStyle> {
IO.mapOptional("ReferenceAlignment", Style.ReferenceAlignment);
IO.mapOptional("ReflowComments", Style.ReflowComments);
IO.mapOptional("RemoveBracesLLVM", Style.RemoveBracesLLVM);
IO.mapOptional("RemoveEmptyLinesInUnwrappedLines",
Style.RemoveEmptyLinesInUnwrappedLines);
IO.mapOptional("RemoveParentheses", Style.RemoveParentheses);
IO.mapOptional("RemoveSemicolon", Style.RemoveSemicolon);
IO.mapOptional("RequiresClausePosition", Style.RequiresClausePosition);
Expand Down Expand Up @@ -1582,6 +1584,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.ReferenceAlignment = FormatStyle::RAS_Pointer;
LLVMStyle.ReflowComments = FormatStyle::RCS_Always;
LLVMStyle.RemoveBracesLLVM = false;
LLVMStyle.RemoveEmptyLinesInUnwrappedLines = false;
LLVMStyle.RemoveParentheses = FormatStyle::RPS_Leave;
LLVMStyle.RemoveSemicolon = false;
LLVMStyle.RequiresClausePosition = FormatStyle::RCPS_OwnLine;
Expand Down
4 changes: 3 additions & 1 deletion clang/lib/Format/TokenAnnotator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5509,8 +5509,10 @@ static bool isAllmanLambdaBrace(const FormatToken &Tok) {
bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
const FormatToken &Right) const {
const FormatToken &Left = *Right.Previous;
if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0)
if (Right.NewlinesBefore > 1 && Style.MaxEmptyLinesToKeep > 0 &&
(!Style.RemoveEmptyLinesInUnwrappedLines || &Right == Line.First)) {
return true;
}

if (Style.BreakFunctionDefinitionParameters && Line.MightBeFunctionDecl &&
Line.mightBeFunctionDefinition() && Left.MightBeFunctionDeclParen &&
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/Format/UnwrappedLineParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2504,6 +2504,11 @@ bool UnwrappedLineParser::parseBracedList(bool IsAngleBracket, bool IsEnum) {
// Assume there are no blocks inside a braced init list apart
// from the ones we explicitly parse out (like lambdas).
FormatTok->setBlockKind(BK_BracedInit);
if (!IsAngleBracket) {
auto *Prev = FormatTok->Previous;
if (Prev && Prev->is(tok::greater))
Prev->setFinalizedType(TT_TemplateCloser);
}
nextToken();
parseBracedList();
break;
Expand Down
12 changes: 2 additions & 10 deletions clang/lib/Sema/Sema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
AnalysisWarnings(*this), ThreadSafetyDeclCache(nullptr),
LateTemplateParser(nullptr), LateTemplateParserCleanup(nullptr),
OpaqueParser(nullptr), CurContext(nullptr), ExternalSource(nullptr),
CurScope(nullptr), Ident_super(nullptr),
StackHandler(Diags), CurScope(nullptr), Ident_super(nullptr),
AMDGPUPtr(std::make_unique<SemaAMDGPU>(*this)),
ARMPtr(std::make_unique<SemaARM>(*this)),
AVRPtr(std::make_unique<SemaAVR>(*this)),
Expand Down Expand Up @@ -562,17 +562,9 @@ Sema::~Sema() {
SemaPPCallbackHandler->reset();
}

void Sema::warnStackExhausted(SourceLocation Loc) {
// Only warn about this once.
if (!WarnedStackExhausted) {
Diag(Loc, diag::warn_stack_exhausted);
WarnedStackExhausted = true;
}
}

void Sema::runWithSufficientStackSpace(SourceLocation Loc,
llvm::function_ref<void()> Fn) {
clang::runWithSufficientStackSpace([&] { warnStackExhausted(Loc); }, Fn);
StackHandler.runWithSufficientStackSpace(Loc, Fn);
}

bool Sema::makeUnavailableInSystemHeader(SourceLocation loc,
Expand Down
4 changes: 3 additions & 1 deletion clang/lib/Sema/SemaFunctionEffects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1540,6 +1540,7 @@ bool Sema::FunctionEffectDiff::shouldDiagnoseConversion(
// matching is better.
return true;
}
break;
case FunctionEffect::Kind::Blocking:
case FunctionEffect::Kind::Allocating:
return false;
Expand All @@ -1563,6 +1564,7 @@ bool Sema::FunctionEffectDiff::shouldDiagnoseRedeclaration(
// All these forms of mismatches are diagnosed.
return true;
}
break;
case FunctionEffect::Kind::Blocking:
case FunctionEffect::Kind::Allocating:
return false;
Expand Down Expand Up @@ -1592,7 +1594,7 @@ Sema::FunctionEffectDiff::shouldDiagnoseMethodOverride(
case Kind::ConditionMismatch:
return OverrideResult::Warn;
}

break;
case FunctionEffect::Kind::Blocking:
case FunctionEffect::Kind::Allocating:
return OverrideResult::NoAction;
Expand Down
4 changes: 3 additions & 1 deletion clang/lib/Sema/SemaHLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,10 @@ static ResourceClass getResourceClass(RegisterType RT) {
return ResourceClass::Sampler;
case RegisterType::C:
case RegisterType::I:
llvm_unreachable("unexpected RegisterType value");
// Deliberately falling through to the unreachable below.
break;
}
llvm_unreachable("unexpected RegisterType value");
}

DeclBindingInfo *ResourceBindings::addDeclBindingInfo(const VarDecl *VD,
Expand Down
13 changes: 9 additions & 4 deletions clang/lib/Sema/SemaRISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ struct RVVIntrinsicDef {

struct RVVOverloadIntrinsicDef {
// Indexes of RISCVIntrinsicManagerImpl::IntrinsicList.
SmallVector<uint16_t, 8> Indexes;
SmallVector<uint32_t, 8> Indexes;
};

} // namespace
Expand Down Expand Up @@ -169,7 +169,7 @@ class RISCVIntrinsicManagerImpl : public sema::RISCVIntrinsicManager {
// List of all RVV intrinsic.
std::vector<RVVIntrinsicDef> IntrinsicList;
// Mapping function name to index of IntrinsicList.
StringMap<uint16_t> Intrinsics;
StringMap<uint32_t> Intrinsics;
// Mapping function name to RVVOverloadIntrinsicDef.
StringMap<RVVOverloadIntrinsicDef> OverloadIntrinsics;

Expand Down Expand Up @@ -399,7 +399,7 @@ void RISCVIntrinsicManagerImpl::InitRVVIntrinsic(
Record.HasFRMRoundModeOp);

// Put into IntrinsicList.
uint16_t Index = IntrinsicList.size();
uint32_t Index = IntrinsicList.size();
assert(IntrinsicList.size() == (size_t)Index &&
"Intrinsics indices overflow.");
IntrinsicList.push_back({BuiltinName, Signature});
Expand Down Expand Up @@ -623,7 +623,12 @@ bool SemaRISCV::CheckBuiltinFunctionCall(const TargetInfo &TI,
ASTContext::BuiltinVectorTypeInfo Info = Context.getBuiltinVectorTypeInfo(
TheCall->getType()->castAs<BuiltinType>());

if (Context.getTypeSize(Info.ElementType) == 64 && !TI.hasFeature("v"))
const FunctionDecl *FD = SemaRef.getCurFunctionDecl();
llvm::StringMap<bool> FunctionFeatureMap;
Context.getFunctionFeatureMap(FunctionFeatureMap, FD);

if (Context.getTypeSize(Info.ElementType) == 64 && !TI.hasFeature("v") &&
!FunctionFeatureMap.lookup("v"))
return Diag(TheCall->getBeginLoc(),
diag::err_riscv_builtin_requires_extension)
<< /* IsExtension */ true << TheCall->getSourceRange() << "v";
Expand Down
3 changes: 1 addition & 2 deletions clang/lib/Sema/SemaTemplateInstantiate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -806,8 +806,7 @@ void Sema::pushCodeSynthesisContext(CodeSynthesisContext Ctx) {

// Check to see if we're low on stack space. We can't do anything about this
// from here, but we can at least warn the user.
if (isStackNearlyExhausted())
warnStackExhausted(Ctx.PointOfInstantiation);
StackHandler.warnOnStackNearlyExhausted(Ctx.PointOfInstantiation);
}

void Sema::popCodeSynthesisContext() {
Expand Down
21 changes: 10 additions & 11 deletions clang/lib/Serialization/ASTReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/SourceManagerInternals.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/Stack.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Basic/TokenKinds.h"
Expand Down Expand Up @@ -9648,18 +9649,15 @@ DiagnosticBuilder ASTReader::Diag(SourceLocation Loc, unsigned DiagID) const {
return Diags.Report(Loc, DiagID);
}

void ASTReader::warnStackExhausted(SourceLocation Loc) {
void ASTReader::runWithSufficientStackSpace(SourceLocation Loc,
llvm::function_ref<void()> Fn) {
// When Sema is available, avoid duplicate errors.
if (SemaObj) {
SemaObj->warnStackExhausted(Loc);
SemaObj->runWithSufficientStackSpace(Loc, Fn);
return;
}

if (WarnedStackExhausted)
return;
WarnedStackExhausted = true;

Diag(Loc, diag::warn_stack_exhausted);
StackHandler.runWithSufficientStackSpace(Loc, Fn);
}

/// Retrieve the identifier table associated with the
Expand Down Expand Up @@ -10509,13 +10507,14 @@ ASTReader::ASTReader(Preprocessor &PP, InMemoryModuleCache &ModuleCache,
bool AllowConfigurationMismatch, bool ValidateSystemInputs,
bool ValidateASTInputFilesContent, bool UseGlobalIndex,
std::unique_ptr<llvm::Timer> ReadTimer)
: Listener(bool(DisableValidationKind &DisableValidationForModuleKind::PCH)
: Listener(bool(DisableValidationKind & DisableValidationForModuleKind::PCH)
? cast<ASTReaderListener>(new SimpleASTReaderListener(PP))
: cast<ASTReaderListener>(new PCHValidator(PP, *this))),
SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
PCHContainerRdr(PCHContainerRdr), Diags(PP.getDiagnostics()), PP(PP),
ContextObj(Context), ModuleMgr(PP.getFileManager(), ModuleCache,
PCHContainerRdr, PP.getHeaderSearchInfo()),
PCHContainerRdr(PCHContainerRdr), Diags(PP.getDiagnostics()),
StackHandler(Diags), PP(PP), ContextObj(Context),
ModuleMgr(PP.getFileManager(), ModuleCache, PCHContainerRdr,
PP.getHeaderSearchInfo()),
DummyIdResolver(PP), ReadTimer(std::move(ReadTimer)), isysroot(isysroot),
DisableValidationKind(DisableValidationKind),
AllowASTWithCompilerErrors(AllowASTWithCompilerErrors),
Expand Down
3 changes: 1 addition & 2 deletions clang/lib/Serialization/ASTReaderDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4168,8 +4168,7 @@ Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) {
D->setDeclContext(Context.getTranslationUnitDecl());

// Reading some declarations can result in deep recursion.
clang::runWithSufficientStackSpace([&] { warnStackExhausted(DeclLoc); },
[&] { Reader.Visit(D); });
runWithSufficientStackSpace(DeclLoc, [&] { Reader.Visit(D); });

// If this declaration is also a declaration context, get the
// offsets for its tables of lexical and visible declarations.
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/StaticAnalyzer/Checkers/BitwiseShiftChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ BugReportPtr BitwiseShiftValidator::checkOvershift() {
RightOpStr = formatv(" '{0}'", ConcreteRight->getValue());
else {
SValBuilder &SVB = Ctx.getSValBuilder();
if (const llvm::APSInt *MinRight = SVB.getMinValue(FoldedState, Right)) {
if (const llvm::APSInt *MinRight = SVB.getMinValue(FoldedState, Right);
MinRight && *MinRight >= LHSBitWidth) {
LowerBoundStr = formatv(" >= {0},", MinRight->getExtValue());
}
}
Expand Down
85 changes: 47 additions & 38 deletions clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1249,6 +1249,8 @@ class SymbolicRangeInferrer
// calculate the effective range set by intersecting the range set
// for A - B and the negated range set of B - A.
getRangeForNegatedSymSym(SSE),
// If commutative, we may have constaints for the commuted variant.
getRangeCommutativeSymSym(SSE),
// If Sym is a comparison expression (except <=>),
// find any other comparisons with the same operands.
// See function description.
Expand Down Expand Up @@ -1485,6 +1487,21 @@ class SymbolicRangeInferrer
Sym->getType());
}

std::optional<RangeSet> getRangeCommutativeSymSym(const SymSymExpr *SSE) {
auto Op = SSE->getOpcode();
bool IsCommutative = llvm::is_contained(
// ==, !=, |, &, +, *, ^
{BO_EQ, BO_NE, BO_Or, BO_And, BO_Add, BO_Mul, BO_Xor}, Op);
if (!IsCommutative)
return std::nullopt;

SymbolRef Commuted = State->getSymbolManager().getSymSymExpr(
SSE->getRHS(), Op, SSE->getLHS(), SSE->getType());
if (const RangeSet *Range = getConstraint(State, Commuted))
return *Range;
return std::nullopt;
}

// Returns ranges only for binary comparison operators (except <=>)
// when left and right operands are symbolic values.
// Finds any other comparisons with the same operands.
Expand Down Expand Up @@ -1936,30 +1953,27 @@ class RangeConstraintManager : public RangedConstraintManager {
const llvm::APSInt &To, const llvm::APSInt &Adjustment) override;

private:
RangeSet::Factory F;
mutable RangeSet::Factory F;

RangeSet getRange(ProgramStateRef State, SymbolRef Sym);
RangeSet getRange(ProgramStateRef State, EquivalenceClass Class);
RangeSet getRange(ProgramStateRef State, SymbolRef Sym) const;
ProgramStateRef setRange(ProgramStateRef State, SymbolRef Sym,
RangeSet Range);
ProgramStateRef setRange(ProgramStateRef State, EquivalenceClass Class,
RangeSet Range);

RangeSet getSymLTRange(ProgramStateRef St, SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment);
const llvm::APSInt &Adjustment) const;
RangeSet getSymGTRange(ProgramStateRef St, SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment);
const llvm::APSInt &Adjustment) const;
RangeSet getSymLERange(ProgramStateRef St, SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment);
const llvm::APSInt &Adjustment) const;
RangeSet getSymLERange(llvm::function_ref<RangeSet()> RS,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment);
const llvm::APSInt &Adjustment) const;
RangeSet getSymGERange(ProgramStateRef St, SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment);
const llvm::APSInt &Adjustment) const;
};

//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -2866,24 +2880,19 @@ ConditionTruthVal RangeConstraintManager::checkNull(ProgramStateRef State,

const llvm::APSInt *RangeConstraintManager::getSymVal(ProgramStateRef St,
SymbolRef Sym) const {
const RangeSet *T = getConstraint(St, Sym);
return T ? T->getConcreteValue() : nullptr;
return getRange(St, Sym).getConcreteValue();
}

const llvm::APSInt *RangeConstraintManager::getSymMinVal(ProgramStateRef St,
SymbolRef Sym) const {
const RangeSet *T = getConstraint(St, Sym);
if (!T || T->isEmpty())
return nullptr;
return &T->getMinValue();
RangeSet Range = getRange(St, Sym);
return Range.isEmpty() ? nullptr : &Range.getMinValue();
}

const llvm::APSInt *RangeConstraintManager::getSymMaxVal(ProgramStateRef St,
SymbolRef Sym) const {
const RangeSet *T = getConstraint(St, Sym);
if (!T || T->isEmpty())
return nullptr;
return &T->getMaxValue();
RangeSet Range = getRange(St, Sym);
return Range.isEmpty() ? nullptr : &Range.getMaxValue();
}

//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -3027,7 +3036,7 @@ RangeConstraintManager::removeDeadBindings(ProgramStateRef State,
}

RangeSet RangeConstraintManager::getRange(ProgramStateRef State,
SymbolRef Sym) {
SymbolRef Sym) const {
return SymbolicRangeInferrer::inferRange(F, State, Sym);
}

Expand Down Expand Up @@ -3082,10 +3091,10 @@ RangeConstraintManager::assumeSymEQ(ProgramStateRef St, SymbolRef Sym,
return setRange(St, Sym, New);
}

RangeSet RangeConstraintManager::getSymLTRange(ProgramStateRef St,
SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) {
RangeSet
RangeConstraintManager::getSymLTRange(ProgramStateRef St, SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) const {
// Before we do any real work, see if the value can even show up.
APSIntType AdjustmentType(Adjustment);
switch (AdjustmentType.testInRange(Int, true)) {
Expand Down Expand Up @@ -3119,10 +3128,10 @@ RangeConstraintManager::assumeSymLT(ProgramStateRef St, SymbolRef Sym,
return setRange(St, Sym, New);
}

RangeSet RangeConstraintManager::getSymGTRange(ProgramStateRef St,
SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) {
RangeSet
RangeConstraintManager::getSymGTRange(ProgramStateRef St, SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) const {
// Before we do any real work, see if the value can even show up.
APSIntType AdjustmentType(Adjustment);
switch (AdjustmentType.testInRange(Int, true)) {
Expand Down Expand Up @@ -3156,10 +3165,10 @@ RangeConstraintManager::assumeSymGT(ProgramStateRef St, SymbolRef Sym,
return setRange(St, Sym, New);
}

RangeSet RangeConstraintManager::getSymGERange(ProgramStateRef St,
SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) {
RangeSet
RangeConstraintManager::getSymGERange(ProgramStateRef St, SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) const {
// Before we do any real work, see if the value can even show up.
APSIntType AdjustmentType(Adjustment);
switch (AdjustmentType.testInRange(Int, true)) {
Expand Down Expand Up @@ -3196,7 +3205,7 @@ RangeConstraintManager::assumeSymGE(ProgramStateRef St, SymbolRef Sym,
RangeSet
RangeConstraintManager::getSymLERange(llvm::function_ref<RangeSet()> RS,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) {
const llvm::APSInt &Adjustment) const {
// Before we do any real work, see if the value can even show up.
APSIntType AdjustmentType(Adjustment);
switch (AdjustmentType.testInRange(Int, true)) {
Expand All @@ -3222,10 +3231,10 @@ RangeConstraintManager::getSymLERange(llvm::function_ref<RangeSet()> RS,
return F.intersect(Default, Lower, Upper);
}

RangeSet RangeConstraintManager::getSymLERange(ProgramStateRef St,
SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) {
RangeSet
RangeConstraintManager::getSymLERange(ProgramStateRef St, SymbolRef Sym,
const llvm::APSInt &Int,
const llvm::APSInt &Adjustment) const {
return getSymLERange([&] { return getRange(St, Sym); }, Int, Adjustment);
}

Expand Down
14 changes: 14 additions & 0 deletions clang/test/AST/ByteCode/builtin-functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,20 @@ namespace fpclassify {
char classify_subnorm [__builtin_fpclassify(-1, -1, -1, +1, -1, 1.0e-38f)];
}

namespace abs {
static_assert(__builtin_abs(14) == 14, "");
static_assert(__builtin_labs(14L) == 14L, "");
static_assert(__builtin_llabs(14LL) == 14LL, "");
static_assert(__builtin_abs(-14) == 14, "");
static_assert(__builtin_labs(-0x14L) == 0x14L, "");
static_assert(__builtin_llabs(-0x141414141414LL) == 0x141414141414LL, "");
#define BITSIZE(x) (sizeof(x) * 8)
constexpr int abs4 = __builtin_abs(1 << (BITSIZE(int) - 1)); // both-error {{must be initialized by a constant expression}}
constexpr long abs6 = __builtin_labs(1L << (BITSIZE(long) - 1)); // both-error {{must be initialized by a constant expression}}
constexpr long long abs8 = __builtin_llabs(1LL << (BITSIZE(long long) - 1)); // both-error {{must be initialized by a constant expression}}
#undef BITSIZE
} // namespace abs

namespace fabs {
static_assert(__builtin_fabs(-14.0) == 14.0, "");
}
Expand Down
22 changes: 22 additions & 0 deletions clang/test/AST/ByteCode/new-delete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,28 @@ static_assert(virt_delete(false)); // both-error {{not an integral constant expr
// both-note {{in call to}}


namespace ToplevelScopeInTemplateArg {
class string {
public:
char *mem;
constexpr string() {
this->mem = new char(1);
}
constexpr ~string() {
delete this->mem;
}
constexpr unsigned size() const { return 4; }
};


template <unsigned N>
void test() {};

void f() {
test<string().size()>();
static_assert(string().size() == 4);
}
}

#else
/// Make sure we reject this prior to C++20
Expand Down
24 changes: 24 additions & 0 deletions clang/test/AST/ByteCode/placement-new.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,3 +300,27 @@ namespace UsedToCrash {
}
int alloc1 = (alloc(), 0);
}

constexpr bool change_union_member() {
union U {
int a;
int b;
};
U u = {.a = 1};
std::construct_at<int>(&u.b, 2);
return u.b == 2;
}
static_assert(change_union_member());

namespace PR48606 {
struct A { mutable int n = 0; };

constexpr bool f() {
A a;
A *p = &a;
p->~A();
std::construct_at<A>(p);
return true;
}
static_assert(f());
}
29 changes: 4 additions & 25 deletions clang/test/Analysis/infeasible-sink.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ void test1(int x) {
}

int a, b, c, d, e;
void test2() {
void test2(void) {

if (a == 0)
return;
Expand All @@ -50,31 +50,10 @@ void test2() {
b = d;
a -= d;

if (a != 0)
return;

clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}

/* The BASELINE passes these checks ('wrning' is used to avoid lit to match)
// The parent state is already infeasible, look at this contradiction:
clang_analyzer_eval(b > 0); // expected-wrning{{FALSE}}
clang_analyzer_eval(b <= 0); // expected-wrning{{FALSE}}
// Crashes with expensive checks.
if (b > 0) {
clang_analyzer_warnIfReached(); // no-warning, OK
if (a != 0)
return;
}
// Should not be reachable.
clang_analyzer_warnIfReached(); // expected-wrning{{REACHABLE}}
*/

// The parent state is already infeasible, but we realize that only if b is
// constrained.
clang_analyzer_eval(b > 0); // expected-warning{{UNKNOWN}}
clang_analyzer_eval(b <= 0); // expected-warning{{UNKNOWN}}
if (b > 0) {
clang_analyzer_warnIfReached(); // no-warning
return;
}
clang_analyzer_warnIfReached(); // no-warning
clang_analyzer_warnIfReached(); // no-warning: Unreachable due to contradiction.
}
33 changes: 30 additions & 3 deletions clang/test/Analysis/unary-sym-expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,39 @@ int test(int x, int y) {
return 42;
}

void test_svalbuilder_simplification(int x, int y) {
void test_svalbuilder_simplification_add(int x, int y) {
if (x + y != 3)
return;
clang_analyzer_eval(-(x + y) == -3); // expected-warning{{TRUE}}
// FIXME Commutativity is not supported yet.
clang_analyzer_eval(-(y + x) == -3); // expected-warning{{UNKNOWN}}
clang_analyzer_eval(-(y + x) == -3); // expected-warning{{TRUE}}
}

void test_svalbuilder_simplification_mul(int x, int y) {
if (x * y != 3)
return;
clang_analyzer_eval(-(x * y) == -3); // expected-warning{{TRUE}}
clang_analyzer_eval(-(y * x) == -3); // expected-warning{{TRUE}}
}

void test_svalbuilder_simplification_and(int x, int y) {
if ((x & y) != 3)
return;
clang_analyzer_eval(-(x & y) == -3); // expected-warning{{TRUE}}
clang_analyzer_eval(-(y & x) == -3); // expected-warning{{TRUE}}
}

void test_svalbuilder_simplification_or(int x, int y) {
if ((x | y) != 3)
return;
clang_analyzer_eval(-(x | y) == -3); // expected-warning{{TRUE}}
clang_analyzer_eval(-(y | x) == -3); // expected-warning{{TRUE}}
}

void test_svalbuilder_simplification_xor(int x, int y) {
if ((x ^ y) != 3)
return;
clang_analyzer_eval(-(x ^ y) == -3); // expected-warning{{TRUE}}
clang_analyzer_eval(-(y ^ x) == -3); // expected-warning{{TRUE}}
}

int test_fp(int flag) {
Expand Down
40 changes: 39 additions & 1 deletion clang/test/CodeGen/RISCV/riscv-inline-asm.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,35 @@
// RUN: %clang_cc1 -triple riscv64 -O2 -emit-llvm %s -o - \
// RUN: | FileCheck %s

// Test RISC-V specific inline assembly constraints.
// Test RISC-V specific inline assembly constraints and modifiers.

long test_r(long x) {
// CHECK-LABEL: define{{.*}} {{i64|i32}} @test_r(
// CHECK: call {{i64|i32}} asm sideeffect "", "=r,r"({{i64|i32}} %{{.*}})
long ret;
asm volatile ("" : "=r"(ret) : "r"(x));
// CHECK: call {{i64|i32}} asm sideeffect "", "=r,r"({{i64|i32}} %{{.*}})
asm volatile ("" : "=r"(ret) : "r"(x));
return ret;
}

long test_cr(long x) {
// CHECK-LABEL: define{{.*}} {{i64|i32}} @test_cr(
// CHECK: call {{i64|i32}} asm sideeffect "", "=^cr,^cr"({{i64|i32}} %{{.*}})
long ret;
asm volatile ("" : "=cr"(ret) : "cr"(x));
return ret;
}

float cf;
double cd;
void test_cf(float f, double d) {
// CHECK-LABEL: define{{.*}} void @test_cf(
// CHECK: call float asm sideeffect "", "=^cf,^cf"(float %{{.*}})
asm volatile("" : "=cf"(cf) : "cf"(f));
// CHECK: call double asm sideeffect "", "=^cf,^cf"(double %{{.*}})
asm volatile("" : "=cf"(cd) : "cf"(d));
}

void test_I(void) {
// CHECK-LABEL: define{{.*}} void @test_I()
Expand Down Expand Up @@ -58,3 +86,13 @@ void test_s(void) {

asm("// %0 %1 %2" :: "S"(&var), "S"(&arr[1][1]), "S"(test_s));
}

// CHECK-LABEL: test_modifiers(
// CHECK: call void asm sideeffect "// ${0:i} ${1:i}", "r,r"({{i32|i64}} %val, i32 37)
// CHECK: call void asm sideeffect "// ${0:z} ${1:z}", "i,i"(i32 0, i32 1)
// CHECK: call void asm sideeffect "// ${0:N}", "r"({{i32|i64}} %val)
void test_modifiers(long val) {
asm volatile("// %i0 %i1" :: "r"(val), "r"(37));
asm volatile("// %z0 %z1" :: "i"(0), "i"(1));
asm volatile("// %N0" :: "r"(val));
}
18 changes: 9 additions & 9 deletions clang/test/CodeGen/math-libcalls-tbaa-indirect-args.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,39 +153,39 @@ _Complex long double test_cargl(_Complex long double cld) {
int ilogbl(long double a);

// CHECK-LABEL: define dso_local i32 @test_ilogb(
// CHECK-SAME: x86_fp80 noundef [[A:%.*]]) local_unnamed_addr #[[ATTR2]] {
// CHECK-SAME: x86_fp80 noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK: [[CALL:%.*]] = tail call i32 @ilogbl(x86_fp80 noundef [[A]]) #[[ATTR5]], !tbaa [[TBAA2]]
//
// CHECK-WIN64-LABEL: define dso_local i32 @test_ilogb(
// CHECK-WIN64-SAME: x86_fp80 noundef [[A:%.*]]) local_unnamed_addr #[[ATTR2]] {
// CHECK-WIN64-SAME: x86_fp80 noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-WIN64: [[CALL:%.*]] = tail call i32 @ilogbl(x86_fp80 noundef [[A]]) #[[ATTR5]], !tbaa [[TBAA2]]
//
// CHECK-I686-LABEL: define dso_local i32 @test_ilogb(
// CHECK-I686-SAME: x86_fp80 noundef [[A:%.*]]) local_unnamed_addr #[[ATTR2]] {
// CHECK-I686-SAME: x86_fp80 noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-I686: [[CALL:%.*]] = tail call i32 @ilogbl(x86_fp80 noundef [[A]]) #[[ATTR5]], !tbaa [[TBAA3]]
//
// CHECK-PPC-LABEL: define dso_local i32 @test_ilogb(
// CHECK-PPC-SAME: ppc_fp128 noundef [[A:%.*]]) local_unnamed_addr #[[ATTR1]] {
// CHECK-PPC-SAME: ppc_fp128 noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-PPC: [[CALL:%.*]] = tail call i32 @ilogbl(ppc_fp128 noundef [[A]]) #[[ATTR3]], !tbaa [[TBAA2]]
//
// CHECK-ARM-LABEL: define dso_local i32 @test_ilogb(
// CHECK-ARM-SAME: double noundef [[A:%.*]]) local_unnamed_addr #[[ATTR1]] {
// CHECK-ARM-SAME: double noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-ARM: [[CALL:%.*]] = tail call i32 @ilogbl(double noundef [[A]]) #[[ATTR2]], !tbaa [[TBAA3]]
//
// CHECK-ARM-HF-LABEL: define dso_local i32 @test_ilogb(
// CHECK-ARM-HF-SAME: double noundef [[A:%.*]]) local_unnamed_addr #[[ATTR1]] {
// CHECK-ARM-HF-SAME: double noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-ARM-HF: [[CALL:%.*]] = tail call i32 @ilogbl(double noundef [[A]]) #[[ATTR2]], !tbaa [[TBAA3]]
//
// CHECK-THUMB-LABEL: define i32 @test_ilogb(
// CHECK-THUMB-SAME: double noundef [[A:%.*]]) local_unnamed_addr #[[ATTR1]] {
// CHECK-THUMB-SAME: double noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-THUMB: [[CALL:%.*]] = tail call i32 @ilogbl(double noundef [[A]]) #[[ATTR2]], !tbaa [[TBAA3]]
//
// CHECK-AARCH-LABEL: define dso_local i32 @test_ilogb(
// CHECK-AARCH-SAME: fp128 noundef [[A:%.*]]) local_unnamed_addr #[[ATTR1]] {
// CHECK-AARCH-SAME: fp128 noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-AARCH: [[CALL:%.*]] = tail call i32 @ilogbl(fp128 noundef [[A]]) #[[ATTR2]], !tbaa [[TBAA2]]
//
// CHECK-SPIR-LABEL: define dso_local spir_func i32 @test_ilogb(
// CHECK-SPIR-SAME: double noundef [[A:%.*]]) local_unnamed_addr #[[ATTR1]] {
// CHECK-SPIR-SAME: double noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] {
// CHECK-SPIR: [[CALL:%.*]] = tail call spir_func i32 @ilogbl(double noundef [[A]]) #[[ATTR3]], !tbaa [[TBAA2]]
//
// CHECK-MINGW32-LABEL: define dso_local i32 @test_ilogb(
Expand Down
16 changes: 16 additions & 0 deletions clang/test/CodeGen/stack-protector-guard.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@
// RUN: %clang_cc1 -mstack-protector-guard=tls -triple riscv64-unknown-elf \
// RUN: -mstack-protector-guard-offset=44 -mstack-protector-guard-reg=tp \
// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefix=RISCV
// RUN: %clang_cc1 -mstack-protector-guard=tls -triple powerpc64-unknown-elf \
// RUN: -mstack-protector-guard-offset=52 -mstack-protector-guard-reg=r13 \
// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefix=POWERPC64
// RUN: %clang_cc1 -mstack-protector-guard=tls -triple ppc32-unknown-elf \
// RUN: -mstack-protector-guard-offset=16 -mstack-protector-guard-reg=r2 \
// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefix=POWERPC32
void foo(int*);
void bar(int x) {
int baz[x];
Expand All @@ -31,3 +37,13 @@ void bar(int x) {
// RISCV: [[ATTR1]] = !{i32 1, !"stack-protector-guard", !"tls"}
// RISCV: [[ATTR2]] = !{i32 1, !"stack-protector-guard-reg", !"tp"}
// RISCV: [[ATTR3]] = !{i32 1, !"stack-protector-guard-offset", i32 44}

// POWERPC64: !llvm.module.flags = !{{{.*}}[[ATTR1:![0-9]+]], [[ATTR2:![0-9]+]], [[ATTR3:![0-9]+]], [[ATTR4:![0-9]+]]}
// POWERPC64: [[ATTR2]] = !{i32 1, !"stack-protector-guard", !"tls"}
// POWERPC64: [[ATTR3]] = !{i32 1, !"stack-protector-guard-reg", !"r13"}
// POWERPC64: [[ATTR4]] = !{i32 1, !"stack-protector-guard-offset", i32 52}

// POWERPC32: !llvm.module.flags = !{{{.*}}[[ATTR1:![0-9]+]], [[ATTR2:![0-9]+]], [[ATTR3:![0-9]+]], [[ATTR4:![0-9]+]]}
// POWERPC32: [[ATTR2]] = !{i32 1, !"stack-protector-guard", !"tls"}
// POWERPC32: [[ATTR3]] = !{i32 1, !"stack-protector-guard-reg", !"r2"}
// POWERPC32: [[ATTR4]] = !{i32 1, !"stack-protector-guard-offset", i32 16}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -o - -emit-llvm -fhalf-no-semantic-interposition | FileCheck %s

// The inline function is emitted in each module with the same comdat
// CHECK: $_ZTS1A = comdat any
// CHECK: $_ZTI1A = comdat any
// CHECK: $_ZTS1A = comdat any
// CHECK: $_ZTI1B.rtti_proxy = comdat any

// The VTable is emitted everywhere used
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
// RUN: %clang_cc1 %s -triple=aarch64-unknown-fuchsia -O1 -o - -emit-llvm | FileCheck %s

// CHECK: $_ZTV1A = comdat any
// CHECK: $_ZTS1A = comdat any
// CHECK: $_ZTI1A = comdat any
// CHECK: $_ZTS1A = comdat any
// CHECK: $_ZTI1A.rtti_proxy = comdat any

// The VTable is linkonce_odr and in a comdat here bc it’s key function is inline defined.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
// CHECK: $_ZN1A3fooEv = comdat any
// CHECK: $_ZN1B3fooEv = comdat any
// CHECK: $_ZTV1A = comdat any
// CHECK: $_ZTS1A = comdat any
// CHECK: $_ZTI1A = comdat any
// CHECK: $_ZTS1A = comdat any
// CHECK: $_ZTI1A.rtti_proxy = comdat any
// CHECK: $_ZTV1B = comdat any
// CHECK: $_ZTS1B = comdat any
// CHECK: $_ZTI1B = comdat any
// CHECK: $_ZTS1B = comdat any
// CHECK: $_ZTI1B.rtti_proxy = comdat any

// Both the vtables for A and B are emitted and in their own comdats.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@
// A::foo() has a comdat since it is an inline function
// CHECK: $_ZN1A3fooEv = comdat any
// CHECK: $_ZTV1A = comdat any
// CHECK: $_ZTI1A = comdat any
// CHECK: $_ZTS1A = comdat any

// The VTable for A has its own comdat section bc it has no key function
// CHECK: $_ZTI1A = comdat any
// CHECK: $_ZTI1A.rtti_proxy = comdat any

// The VTable for A is emitted here and in a comdat section since it has no key function, and is used in this module when creating an instance of A.
// CHECK: @_ZTV1A.local = linkonce_odr hidden unnamed_addr constant { [3 x i32] } { [3 x i32] [i32 0, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1A.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [3 x i32] }, ptr @_ZTV1A.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1A3fooEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [3 x i32] }, ptr @_ZTV1A.local, i32 0, i32 0, i32 2) to i64)) to i32)] }, comdat($_ZTV1A), align 4
// CHECK: @_ZTI1A = linkonce_odr constant { ptr, ptr } { ptr getelementptr inbounds (i8, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i32 8), ptr @_ZTS1A }, comdat, align 8
// CHECK: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr]
// CHECK: @_ZTS1A = linkonce_odr constant [3 x i8] c"1A\00", comdat, align 1
// CHECK: @_ZTI1A = linkonce_odr constant { ptr, ptr } { ptr getelementptr inbounds (i8, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i32 8), ptr @_ZTS1A }, comdat, align 8
// CHECK: @_ZTI1A.rtti_proxy = linkonce_odr hidden unnamed_addr constant ptr @_ZTI1A, comdat
// CHECK: @_ZTV1A = linkonce_odr unnamed_addr alias { [3 x i32] }, ptr @_ZTV1A.local

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
// The vtable definition itself is private so we can take relative references to
// it. The vtable symbol will be exposed through a public alias.
// CHECK: @_ZTV1A.local = internal unnamed_addr constant { [3 x i32] } { [3 x i32] [i32 0, i32 trunc (i64 sub (i64 ptrtoint (ptr @_ZTI1A.rtti_proxy to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [3 x i32] }, ptr @_ZTV1A.local, i32 0, i32 0, i32 2) to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint (ptr dso_local_equivalent @_ZN1A3fooEv to i64), i64 ptrtoint (ptr getelementptr inbounds ({ [3 x i32] }, ptr @_ZTV1A.local, i32 0, i32 0, i32 2) to i64)) to i32)] }, align 4
// CHECK: @_ZTI1A ={{.*}} constant { ptr, ptr } { ptr getelementptr inbounds (i8, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i32 8), ptr @_ZTS1A }, align 8
// CHECK: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr]
// CHECK: @_ZTS1A ={{.*}} constant [3 x i8] c"1A\00", align 1
// CHECK: @_ZTI1A ={{.*}} constant { ptr, ptr } { ptr getelementptr inbounds (i8, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i32 8), ptr @_ZTS1A }, align 8

// The rtti should be in a comdat
// CHECK: @_ZTI1A.rtti_proxy = {{.*}}comdat
Expand Down
4 changes: 2 additions & 2 deletions clang/test/CodeGenCXX/RelativeVTablesABI/type-info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
// CHECK: $_ZTI1A.rtti_proxy = comdat any
// CHECK: $_ZTI1B.rtti_proxy = comdat any

// CHECK: @_ZTI1A ={{.*}} constant { ptr, ptr } { ptr getelementptr inbounds (i8, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i32 8), ptr @_ZTS1A }, align 8
// CHECK: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr]
// CHECK: @_ZTS1A ={{.*}} constant [3 x i8] c"1A\00", align 1
// CHECK: @_ZTI1A ={{.*}} constant { ptr, ptr } { ptr getelementptr inbounds (i8, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i32 8), ptr @_ZTS1A }, align 8
// CHECK: @_ZTI1B ={{.*}} constant { ptr, ptr, ptr } { ptr getelementptr inbounds (i8, ptr @_ZTVN10__cxxabiv120__si_class_type_infoE, i32 8), ptr @_ZTS1B, ptr @_ZTI1A }, align 8
// CHECK: @_ZTVN10__cxxabiv120__si_class_type_infoE = external global [0 x ptr]
// CHECK: @_ZTS1B ={{.*}} constant [3 x i8] c"1B\00", align 1
// CHECK: @_ZTI1B ={{.*}} constant { ptr, ptr, ptr } { ptr getelementptr inbounds (i8, ptr @_ZTVN10__cxxabiv120__si_class_type_infoE, i32 8), ptr @_ZTS1B, ptr @_ZTI1A }, align 8
// CHECK: @_ZTI1A.rtti_proxy = linkonce_odr hidden unnamed_addr constant ptr @_ZTI1A, comdat
// CHECK: @_ZTI1B.rtti_proxy = linkonce_odr hidden unnamed_addr constant ptr @_ZTI1B, comdat

Expand Down
86 changes: 85 additions & 1 deletion clang/test/CodeGenCXX/aarch64-mangle-sve-vectors.cpp

Large diffs are not rendered by default.

70 changes: 70 additions & 0 deletions clang/test/CodeGenCXX/aarch64-sve-vector-init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@
// CHECK-NEXT: [[B8X2:%.*]] = alloca { <vscale x 16 x i1>, <vscale x 16 x i1> }, align 2
// CHECK-NEXT: [[B8X4:%.*]] = alloca { <vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1> }, align 2
// CHECK-NEXT: [[CNT:%.*]] = alloca target("aarch64.svcount"), align 2
// CHECK-NEXT: [[MF8X2:%.*]] = alloca { <vscale x 16 x i8>, <vscale x 16 x i8> }, align 16
// CHECK-NEXT: [[MF8X3:%.*]] = alloca { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> }, align 16
// CHECK-NEXT: [[MF8X4:%.*]] = alloca { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> }, align 16
// CHECK-NEXT: store <vscale x 16 x i8> zeroinitializer, ptr [[S8]], align 16
// CHECK-NEXT: store <vscale x 8 x i16> zeroinitializer, ptr [[S16]], align 16
// CHECK-NEXT: store <vscale x 4 x i32> zeroinitializer, ptr [[S32]], align 16
Expand Down Expand Up @@ -110,6 +113,9 @@
// CHECK-NEXT: store { <vscale x 16 x i1>, <vscale x 16 x i1> } zeroinitializer, ptr [[B8X2]], align 2
// CHECK-NEXT: store { <vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1>, <vscale x 16 x i1> } zeroinitializer, ptr [[B8X4]], align 2
// CHECK-NEXT: store target("aarch64.svcount") zeroinitializer, ptr [[CNT]], align 2
// CHECK-NEXT: store { <vscale x 16 x i8>, <vscale x 16 x i8> } zeroinitializer, ptr [[MF8X2]], align 16
// CHECK-NEXT: store { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } zeroinitializer, ptr [[MF8X3]], align 16
// CHECK-NEXT: store { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } zeroinitializer, ptr [[MF8X4]], align 16
// CHECK-NEXT: ret void
//
void test_locals(void) {
Expand Down Expand Up @@ -171,6 +177,10 @@ void test_locals(void) {
__clang_svboolx4_t b8x4{};

__SVCount_t cnt{};

__clang_svmfloat8x2_t mf8x2{};
__clang_svmfloat8x3_t mf8x3{};
__clang_svmfloat8x4_t mf8x4{};
}

// CHECK-LABEL: define dso_local void @_Z12test_copy_s8u10__SVInt8_t
Expand Down Expand Up @@ -1142,3 +1152,63 @@ void test_copy_b8x4(__clang_svboolx4_t a) {
void test_copy_cnt(__SVCount_t a) {
__SVCount_t b{a};
}

// CHECK-LABEL: define dso_local void @_Z15test_copy_mf8x213svmfloat8x2_t
// CHECK-SAME: (<vscale x 16 x i8> [[A_COERCE0:%.*]], <vscale x 16 x i8> [[A_COERCE1:%.*]]) #[[ATTR0]] {
// CHECK-NEXT: entry:
// CHECK-NEXT: [[A:%.*]] = alloca { <vscale x 16 x i8>, <vscale x 16 x i8> }, align 16
// CHECK-NEXT: [[A_ADDR:%.*]] = alloca { <vscale x 16 x i8>, <vscale x 16 x i8> }, align 16
// CHECK-NEXT: [[B:%.*]] = alloca { <vscale x 16 x i8>, <vscale x 16 x i8> }, align 16
// CHECK-NEXT: [[TMP0:%.*]] = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8> } poison, <vscale x 16 x i8> [[A_COERCE0]], 0
// CHECK-NEXT: [[TMP1:%.*]] = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP0]], <vscale x 16 x i8> [[A_COERCE1]], 1
// CHECK-NEXT: store { <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP1]], ptr [[A]], align 16
// CHECK-NEXT: [[A1:%.*]] = load { <vscale x 16 x i8>, <vscale x 16 x i8> }, ptr [[A]], align 16
// CHECK-NEXT: store { <vscale x 16 x i8>, <vscale x 16 x i8> } [[A1]], ptr [[A_ADDR]], align 16
// CHECK-NEXT: [[TMP2:%.*]] = load { <vscale x 16 x i8>, <vscale x 16 x i8> }, ptr [[A_ADDR]], align 16
// CHECK-NEXT: store { <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP2]], ptr [[B]], align 16
// CHECK-NEXT: ret void
//
void test_copy_mf8x2(__clang_svmfloat8x2_t a) {
__clang_svmfloat8x2_t b{a};
}

// CHECK-LABEL: define dso_local void @_Z15test_copy_mf8x313svmfloat8x3_t
// CHECK-SAME: (<vscale x 16 x i8> [[A_COERCE0:%.*]], <vscale x 16 x i8> [[A_COERCE1:%.*]], <vscale x 16 x i8> [[A_COERCE2:%.*]]) #[[ATTR0]] {
// CHECK-NEXT: entry:
// CHECK-NEXT: [[A:%.*]] = alloca { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> }, align 16
// CHECK-NEXT: [[A_ADDR:%.*]] = alloca { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> }, align 16
// CHECK-NEXT: [[B:%.*]] = alloca { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> }, align 16
// CHECK-NEXT: [[TMP0:%.*]] = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } poison, <vscale x 16 x i8> [[A_COERCE0]], 0
// CHECK-NEXT: [[TMP1:%.*]] = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP0]], <vscale x 16 x i8> [[A_COERCE1]], 1
// CHECK-NEXT: [[TMP2:%.*]] = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP1]], <vscale x 16 x i8> [[A_COERCE2]], 2
// CHECK-NEXT: store { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP2]], ptr [[A]], align 16
// CHECK-NEXT: [[A1:%.*]] = load { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> }, ptr [[A]], align 16
// CHECK-NEXT: store { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[A1]], ptr [[A_ADDR]], align 16
// CHECK-NEXT: [[TMP3:%.*]] = load { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> }, ptr [[A_ADDR]], align 16
// CHECK-NEXT: store { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP3]], ptr [[B]], align 16
// CHECK-NEXT: ret void
//
void test_copy_mf8x3(__clang_svmfloat8x3_t a) {
__clang_svmfloat8x3_t b{a};
}

// CHECK-LABEL: define dso_local void @_Z15test_copy_mf8x413svmfloat8x4_t
// CHECK-SAME: (<vscale x 16 x i8> [[A_COERCE0:%.*]], <vscale x 16 x i8> [[A_COERCE1:%.*]], <vscale x 16 x i8> [[A_COERCE2:%.*]], <vscale x 16 x i8> [[A_COERCE3:%.*]]) #[[ATTR0]] {
// CHECK-NEXT: entry:
// CHECK-NEXT: [[A:%.*]] = alloca { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> }, align 16
// CHECK-NEXT: [[A_ADDR:%.*]] = alloca { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> }, align 16
// CHECK-NEXT: [[B:%.*]] = alloca { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> }, align 16
// CHECK-NEXT: [[TMP0:%.*]] = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } poison, <vscale x 16 x i8> [[A_COERCE0]], 0
// CHECK-NEXT: [[TMP1:%.*]] = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP0]], <vscale x 16 x i8> [[A_COERCE1]], 1
// CHECK-NEXT: [[TMP2:%.*]] = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP1]], <vscale x 16 x i8> [[A_COERCE2]], 2
// CHECK-NEXT: [[TMP3:%.*]] = insertvalue { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP2]], <vscale x 16 x i8> [[A_COERCE3]], 3
// CHECK-NEXT: store { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP3]], ptr [[A]], align 16
// CHECK-NEXT: [[A1:%.*]] = load { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> }, ptr [[A]], align 16
// CHECK-NEXT: store { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[A1]], ptr [[A_ADDR]], align 16
// CHECK-NEXT: [[TMP4:%.*]] = load { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> }, ptr [[A_ADDR]], align 16
// CHECK-NEXT: store { <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8>, <vscale x 16 x i8> } [[TMP4]], ptr [[B]], align 16
// CHECK-NEXT: ret void
//
void test_copy_mf8x4(__clang_svmfloat8x4_t a) {
__clang_svmfloat8x4_t b{a};
}
6 changes: 3 additions & 3 deletions clang/test/CodeGenCXX/armv7k.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,17 @@ namespace test2 {

struct __attribute__((visibility("hidden"))) B {};
const std::type_info &b0 = typeid(B);
// CHECK-GLOBALS: @_ZTSN5test21BE = linkonce_odr hidden constant
// CHECK-GLOBALS: @_ZTIN5test21BE = linkonce_odr hidden constant { {{.*}}, ptr @_ZTSN5test21BE }
// CHECK-GLOBALS: @_ZTSN5test21BE = linkonce_odr hidden constant

const std::type_info &b1 = typeid(B*);
// CHECK-GLOBALS: @_ZTSPN5test21BE = linkonce_odr hidden constant
// CHECK-GLOBALS: @_ZTIPN5test21BE = linkonce_odr hidden constant { {{.*}}, ptr @_ZTSPN5test21BE, i32 0, ptr @_ZTIN5test21BE
// CHECK-GLOBALS: @_ZTSPN5test21BE = linkonce_odr hidden constant

struct C {};
const std::type_info &c0 = typeid(C);
// CHECK-GLOBALS: @_ZTSN5test21CE = linkonce_odr constant [11 x i8] c"N5test21CE\00"
// CHECK-GLOBALS: @_ZTIN5test21CE = linkonce_odr constant { {{.*}}, ptr @_ZTSN5test21CE }
// CHECK-GLOBALS: @_ZTSN5test21CE = linkonce_odr constant [11 x i8] c"N5test21CE\00"
}

// va_list should be based on "char *" rather than "ptr".
Expand Down
14 changes: 6 additions & 8 deletions clang/test/CodeGenCXX/builtins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ int o = X::__builtin_fabs(-2.0);
long p = X::__builtin_fabsf(-3.0f);
// CHECK: @p ={{.*}} global i64 3, align 8

int x = __builtin_abs(-2);
// CHECK: @x ={{.*}} global i32 2, align 4

long y = __builtin_abs(-2l);
// CHECK: @y ={{.*}} global i64 2, align 8

// PR8839
extern "C" char memmove();

Expand Down Expand Up @@ -52,14 +58,6 @@ extern "C" int __builtin_abs(int); // #1
long __builtin_abs(long); // #2
extern "C" int __builtin_abs(int); // #3

int x = __builtin_abs(-2);
// CHECK: [[X:%.+]] = call i32 @llvm.abs.i32(i32 -2, i1 true)
// CHECK-NEXT: store i32 [[X]], ptr @x, align 4

long y = __builtin_abs(-2l);
// CHECK: [[Y:%.+]] = call noundef i64 @_Z13__builtin_absl(i64 noundef -2)
// CHECK: store i64 [[Y]], ptr @y, align 8

extern const char char_memchr_arg[32];
char *memchr_result = __builtin_char_memchr(char_memchr_arg, 123, 32);
// CHECK: call ptr @memchr(ptr noundef @char_memchr_arg, i32 noundef 123, i64 noundef 32)
Expand Down
4 changes: 2 additions & 2 deletions clang/test/CodeGenCXX/dynamic-cast-address-space.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ B fail;
// CHECK: @_ZTV1B = linkonce_odr unnamed_addr addrspace(1) constant { [3 x ptr addrspace(1)] } { [3 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) @_ZTI1B, ptr addrspace(1) addrspacecast (ptr @_ZN1A1fEv to ptr addrspace(1))] }, comdat, align 8
// CHECK: @fail = addrspace(1) global { ptr addrspace(1) } { ptr addrspace(1) getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1B, i32 0, i32 0, i32 2) }, align 8
// CHECK: @_ZTI1A = external addrspace(1) constant ptr addrspace(1)
// CHECK: @_ZTI1B = linkonce_odr addrspace(1) constant { ptr addrspace(1), ptr addrspace(1), ptr addrspace(1) } { ptr addrspace(1) getelementptr inbounds (ptr addrspace(1), ptr addrspace(1) @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2), ptr addrspace(1) @_ZTS1B, ptr addrspace(1) @_ZTI1A }, comdat, align 8
// CHECK: @_ZTVN10__cxxabiv120__si_class_type_infoE = external addrspace(1) global [0 x ptr addrspace(1)]
// CHECK: @_ZTS1B = linkonce_odr addrspace(1) constant [3 x i8] c"1B\00", comdat, align 1
// CHECK: @_ZTI1B = linkonce_odr addrspace(1) constant { ptr addrspace(1), ptr addrspace(1), ptr addrspace(1) } { ptr addrspace(1) getelementptr inbounds (ptr addrspace(1), ptr addrspace(1) @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2), ptr addrspace(1) @_ZTS1B, ptr addrspace(1) @_ZTI1A }, comdat, align 8
// CHECK: @__oclc_ABI_version = weak_odr hidden local_unnamed_addr addrspace(4) constant i32 500
//.
// WITH-NONZERO-DEFAULT-AS: @_ZTV1B = linkonce_odr unnamed_addr addrspace(1) constant { [3 x ptr addrspace(1)] } { [3 x ptr addrspace(1)] [ptr addrspace(1) null, ptr addrspace(1) @_ZTI1B, ptr addrspace(1) addrspacecast (ptr addrspace(4) @_ZN1A1fEv to ptr addrspace(1))] }, comdat, align 8
// WITH-NONZERO-DEFAULT-AS: @fail = addrspace(1) global { ptr addrspace(1) } { ptr addrspace(1) getelementptr inbounds inrange(-16, 8) ({ [3 x ptr addrspace(1)] }, ptr addrspace(1) @_ZTV1B, i32 0, i32 0, i32 2) }, align 8
// WITH-NONZERO-DEFAULT-AS: @_ZTI1A = external addrspace(1) constant ptr addrspace(1)
// WITH-NONZERO-DEFAULT-AS: @_ZTI1B = linkonce_odr addrspace(1) constant { ptr addrspace(1), ptr addrspace(1), ptr addrspace(1) } { ptr addrspace(1) getelementptr inbounds (ptr addrspace(1), ptr addrspace(1) @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2), ptr addrspace(1) @_ZTS1B, ptr addrspace(1) @_ZTI1A }, comdat, align 8
// WITH-NONZERO-DEFAULT-AS: @_ZTVN10__cxxabiv120__si_class_type_infoE = external addrspace(1) global [0 x ptr addrspace(1)]
// WITH-NONZERO-DEFAULT-AS: @_ZTS1B = linkonce_odr addrspace(1) constant [3 x i8] c"1B\00", comdat, align 1
// WITH-NONZERO-DEFAULT-AS: @_ZTI1B = linkonce_odr addrspace(1) constant { ptr addrspace(1), ptr addrspace(1), ptr addrspace(1) } { ptr addrspace(1) getelementptr inbounds (ptr addrspace(1), ptr addrspace(1) @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2), ptr addrspace(1) @_ZTS1B, ptr addrspace(1) @_ZTI1A }, comdat, align 8
//.
// CHECK-LABEL: define dso_local noundef nonnull align 8 dereferenceable(8) ptr @_Z1fP1A(
// CHECK-SAME: ptr noundef [[A:%.*]]) #[[ATTR0:[0-9]+]] personality ptr @__gxx_personality_v0 {
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenCXX/exceptions-no-rtti.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
// CHECK: @_ZTIN5test11AE = linkonce_odr constant
// CHECK: @_ZTIN5test11BE = linkonce_odr constant
// CHECK: @_ZTIN5test11CE = linkonce_odr constant
// CHECK: @_ZTIN5test11DE = linkonce_odr constant
// CHECK: @_ZTIPN5test11DE = linkonce_odr constant {{.*}} @_ZTIN5test11DE
// CHECK: @_ZTIN5test11DE = linkonce_odr constant

// PR6974: this shouldn't crash
namespace test0 {
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenCXX/implicit-record-visibility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
// under -fvisibility=hidden the type of function f, due to its va_list (aka
// __builtin_va_list, aka __va_list_tag (*)[1]) parameter would be hidden:

// CHECK: @_ZTSFvP13__va_list_tagE = linkonce_odr constant
// CHECK: @_ZTIFvP13__va_list_tagE = linkonce_odr constant
// CHECK: @_ZTSFvP13__va_list_tagE = linkonce_odr constant
void f(va_list) { (void)typeid(f); }
480 changes: 240 additions & 240 deletions clang/test/CodeGenCXX/mdefault-visibility-export-mapping-rtti.cpp

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions clang/test/CodeGenCXX/modules-vtable.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ inline
Base::~Base() {}

// CHECK: @_ZTVW3Mod4Base = unnamed_addr constant
// CHECK: @_ZTSW3Mod4Base = constant
// CHECK: @_ZTIW3Mod4Base = constant
// CHECK: @_ZTSW3Mod4Base = constant

// With the new Itanium C++ ABI, the linkage of vtables in modules don't need to be linkonce ODR.
// CHECK-INLINE: @_ZTVW3Mod4Base = {{.*}}unnamed_addr constant
// CHECK-INLINE: @_ZTSW3Mod4Base = {{.*}}constant
// CHECK-INLINE: @_ZTIW3Mod4Base = {{.*}}constant
// CHECK-INLINE: @_ZTSW3Mod4Base = {{.*}}constant

module :private;
int private_use() {
Expand All @@ -61,12 +61,12 @@ int use() {
return 43;
}

// CHECK-NOT: @_ZTSW3Mod4Base
// CHECK-NOT: @_ZTIW3Mod4Base
// CHECK-NOT: @_ZTSW3Mod4Base
// CHECK: @_ZTVW3Mod4Base = external

// CHECK-INLINE-NOT: @_ZTSW3Mod4Base
// CHECK-INLINE-NOT: @_ZTIW3Mod4Base
// CHECK-INLINE-NOT: @_ZTSW3Mod4Base
// CHECK-INLINE: @_ZTVW3Mod4Base = external

// Check the case that the declaration of the key function comes from another
Expand All @@ -86,8 +86,8 @@ int a_use() {
}

// CHECK: @_ZTVW1M1C = unnamed_addr constant
// CHECK: @_ZTSW1M1C = constant
// CHECK: @_ZTIW1M1C = constant
// CHECK: @_ZTSW1M1C = constant

//--- M-B.cppm
export module M:B;
Expand All @@ -101,5 +101,5 @@ int b_use() {
}

// CHECK: @_ZTVW1M1C = external
// CHECK-NOT: @_ZTSW1M1C
// CHECK-NOT: @_ZTIW1M1C
// CHECK-NOT: @_ZTSW1M1C
4 changes: 2 additions & 2 deletions clang/test/CodeGenCXX/ptrauth-rtti-layout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@

struct A { int a; };

// DARWIN: @_ZTI1A = linkonce_odr hidden constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2), ptr inttoptr (i64 add (i64 ptrtoint (ptr @_ZTS1A to i64), i64 -9223372036854775808) to ptr) }
// DARWIN: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr]
// DARWIN: @_ZTS1A = linkonce_odr hidden constant [3 x i8] c"1A\00"
// DARWIN: @_ZTI1A = linkonce_odr hidden constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2), ptr inttoptr (i64 add (i64 ptrtoint (ptr @_ZTS1A to i64), i64 -9223372036854775808) to ptr) }

// ELF: @_ZTI1A = linkonce_odr constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2), ptr @_ZTS1A }
// ELF: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr]
// ELF: @_ZTS1A = linkonce_odr constant [3 x i8] c"1A\00"
// ELF: @_ZTI1A = linkonce_odr constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2), ptr @_ZTS1A }

auto ATI = typeid(A);
7 changes: 4 additions & 3 deletions clang/test/CodeGenCXX/ptrauth-type-info-vtable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,13 @@ static_assert(__has_feature(ptrauth_type_info_vtable_pointer_discrimination) ==
extern "C" int disc_std_type_info = __builtin_ptrauth_string_discriminator("_ZTVSt9type_info");

// CHECK: @_ZTV10TestStruct = unnamed_addr constant { [4 x ptr] } { [4 x ptr] [ptr null, ptr @_ZTI10TestStruct, ptr ptrauth (ptr @_ZN10TestStructD1Ev, i32 0, i64 52216, ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV10TestStruct, i32 0, i32 0, i32 2)), ptr ptrauth (ptr @_ZN10TestStructD0Ev, i32 0, i64 39671, ptr getelementptr inbounds ({ [4 x ptr] }, ptr @_ZTV10TestStruct, i32 0, i32 0, i32 3))] }, align 8
// CHECK: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr]
// CHECK: @_ZTS10TestStruct = constant [13 x i8] c"10TestStruct\00", align 1

// NODISC: @_ZTI10TestStruct = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2), ptr @_ZTS10TestStruct }, align 8

// DISC: @_ZTI10TestStruct = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2, i64 [[STDTYPEINFO_DISC]]), ptr @_ZTS10TestStruct }, align 8
// DISC: @_ZTI10TestStruct = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2, i64 [[STDTYPEINFO_DISC]], ptr @_ZTI10TestStruct), ptr @_ZTS10TestStruct }, align 8

// CHECK: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr]
// CHECK: @_ZTS10TestStruct = constant [13 x i8] c"10TestStruct\00", align 1

struct TestStruct {
virtual ~TestStruct();
Expand Down
26 changes: 13 additions & 13 deletions clang/test/CodeGenCXX/ptrauth-vtable-virtual-inheritance-thunk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,41 +94,41 @@
// CHECK-SAME: ptr ptrauth (ptr @_ZN1AD1Ev, i32 0, i64 2043, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 5)),
// CHECK-SAME: ptr ptrauth (ptr @_ZN1AD0Ev, i32 0, i64 63674, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1A, i32 0, i32 0, i32 6))] }, align 8

// CHECK: @_ZTI1A = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2), ptr @_ZTS1A }, align 8

// CHECK: @_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr]

// CHECK: @_ZTS1A = constant [3 x i8] c"1A\00", align 1

// CHECK: @_ZTI1A = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2), ptr @_ZTS1A }, align 8
// CHECK: @_ZTI1C = constant { ptr, ptr, i32, i32, ptr, i64 } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2), i32 2), ptr @_ZTS1C, i32 0, i32 1, ptr @_ZTI1B, i64 -6141 }, align 8

// CHECK: @_ZTVN10__cxxabiv121__vmi_class_type_infoE = external global [0 x ptr]

// CHECK: @_ZTS1C = constant [3 x i8] c"1C\00", align 1

// DARWIN: @_ZTI1B = linkonce_odr hidden constant { ptr, ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2), i32 2), ptr inttoptr (i64 add (i64 ptrtoint (ptr @_ZTS1B to i64), i64 -9223372036854775808) to ptr), ptr @_ZTI1A }, align 8
// ELF: @_ZTI1B = linkonce_odr constant { ptr, ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2), i32 2), ptr @_ZTS1B, ptr @_ZTI1A }, comdat, align 8

// CHECK: @_ZTVN10__cxxabiv120__si_class_type_infoE = external global [0 x ptr]

// DARWIN: @_ZTS1B = linkonce_odr hidden constant [3 x i8] c"1B\00", align 1
// ELF: @_ZTS1B = linkonce_odr constant [3 x i8] c"1B\00", comdat, align 1

// DARWIN: @_ZTI1B = linkonce_odr hidden constant { ptr, ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2), i32 2), ptr inttoptr (i64 add (i64 ptrtoint (ptr @_ZTS1B to i64), i64 -9223372036854775808) to ptr), ptr @_ZTI1A }, align 8
// ELF: @_ZTI1B = linkonce_odr constant { ptr, ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv120__si_class_type_infoE, i64 2), i32 2), ptr @_ZTS1B, ptr @_ZTI1A }, comdat, align 8

// CHECK: @_ZTI1C = constant { ptr, ptr, i32, i32, ptr, i64 } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2), i32 2), ptr @_ZTS1C, i32 0, i32 1, ptr @_ZTI1B, i64 -6141 }, align 8
// CHECK: @_ZTI1D = constant { ptr, ptr, i32, i32, ptr, i64 } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2), i32 2), ptr @_ZTS1D, i32 0, i32 1, ptr @_ZTI1B, i64 -6141 }, align 8

// CHECK: @_ZTS1D = constant [3 x i8] c"1D\00", align 1

// CHECK: @_ZTI1D = constant { ptr, ptr, i32, i32, ptr, i64 } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2), i32 2), ptr @_ZTS1D, i32 0, i32 1, ptr @_ZTI1B, i64 -6141 }, align 8

// CHECK: @_ZTV1E = unnamed_addr constant { [7 x ptr] } { [7 x ptr] [ptr null, ptr @_ZTI1E,
// CHECK-SAME: ptr ptrauth (ptr @_ZN1E1fEv, i32 0, i64 28408, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1E, i32 0, i32 0, i32 2)),
// CHECK-SAME: ptr ptrauth (ptr @_ZN1E1gEv, i32 0, i64 22926, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1E, i32 0, i32 0, i32 3)),
// CHECK-SAME: ptr ptrauth (ptr @_ZN1E1hEz, i32 0, i64 9832, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1E, i32 0, i32 0, i32 4)),
// CHECK-SAME: ptr ptrauth (ptr @_ZN1ED1Ev, i32 0, i64 5817, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1E, i32 0, i32 0, i32 5)),
// CHECK-SAME: ptr ptrauth (ptr @_ZN1ED0Ev, i32 0, i64 26464, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1E, i32 0, i32 0, i32 6))] }, align 8

// CHECK: @_ZTS1E = constant [3 x i8] c"1E\00", align 1

// CHECK: @_ZTI1E = constant { ptr, ptr } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv117__class_type_infoE, i64 2), i32 2), ptr @_ZTS1E }, align 8

// CHECK: @_ZTS1E = constant [3 x i8] c"1E\00", align 1

// CHECK: @_ZTC1F0_1C = unnamed_addr constant { [5 x ptr], [11 x ptr] } { [5 x ptr] [ptr inttoptr (i64 16 to ptr), ptr null, ptr @_ZTI1C,
// CHECK-SAME: ptr ptrauth (ptr @_ZN1CD1Ev, i32 0, i64 31214, ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1F0_1C, i32 0, i32 0, i32 3)),
// CHECK-SAME: ptr ptrauth (ptr @_ZN1CD0Ev, i32 0, i64 8507, ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1F0_1C, i32 0, i32 0, i32 4))], [11 x ptr] [ptr inttoptr (i64 -16 to ptr), ptr null, ptr null, ptr null, ptr inttoptr (i64 -16 to ptr), ptr @_ZTI1C,
Expand All @@ -149,10 +149,10 @@
// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1DD1Ev, i32 0, i64 2043, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1F8_1D, i32 0, i32 1, i32 9)),
// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1DD0Ev, i32 0, i64 63674, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1F8_1D, i32 0, i32 1, i32 10))] }, align 8

// CHECK: @_ZTS1F = constant [3 x i8] c"1F\00", align 1

// CHECK: @_ZTI1F = constant { ptr, ptr, i32, i32, ptr, i64, ptr, i64, ptr, i64 } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2), i32 2), ptr @_ZTS1F, i32 3, i32 3, ptr @_ZTI1C, i64 2, ptr @_ZTI1D, i64 2050, ptr @_ZTI1E, i64 -8189 }, align 8

// CHECK: @_ZTS1F = constant [3 x i8] c"1F\00", align 1

// CHECK: @_ZTC1G0_1C = unnamed_addr constant { [5 x ptr], [11 x ptr] } { [5 x ptr] [ptr inttoptr (i64 24 to ptr), ptr null, ptr @_ZTI1C,
// CHECK-SAME: ptr ptrauth (ptr @_ZN1CD1Ev, i32 0, i64 31214, ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1G0_1C, i32 0, i32 0, i32 3)),
// CHECK-SAME: ptr ptrauth (ptr @_ZN1CD0Ev, i32 0, i64 8507, ptr getelementptr inbounds ({ [5 x ptr], [11 x ptr] }, ptr @_ZTC1G0_1C, i32 0, i32 0, i32 4))], [11 x ptr] [ptr inttoptr (i64 -24 to ptr), ptr null, ptr null, ptr null, ptr inttoptr (i64 -24 to ptr), ptr @_ZTI1C,
Expand All @@ -173,10 +173,10 @@
// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1DD1Ev, i32 0, i64 2043, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1G8_1D, i32 0, i32 1, i32 9)),
// CHECK-SAME: ptr ptrauth (ptr @_ZTv0_n48_N1DD0Ev, i32 0, i64 63674, ptr getelementptr inbounds ({ [7 x ptr], [11 x ptr] }, ptr @_ZTC1G8_1D, i32 0, i32 1, i32 10))] }, align 8

// CHECK: @_ZTS1G = constant [3 x i8] c"1G\00", align 1

// CHECK: @_ZTI1G = constant { ptr, ptr, i32, i32, ptr, i64, ptr, i64, ptr, i64 } { ptr ptrauth (ptr getelementptr inbounds (ptr, ptr @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2), i32 2), ptr @_ZTS1G, i32 3, i32 3, ptr @_ZTI1E, i64 -8189, ptr @_ZTI1C, i64 2, ptr @_ZTI1D, i64 2050 }, align 8

// CHECK: @_ZTS1G = constant [3 x i8] c"1G\00", align 1

// CHECK: @_ZTV1B = linkonce_odr unnamed_addr constant { [7 x ptr] } { [7 x ptr] [ptr null, ptr @_ZTI1B,
// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1fEv, i32 0, i64 55636, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 2)),
// CHECK-SAME: ptr ptrauth (ptr @_ZN1A1gEv, i32 0, i64 19402, ptr getelementptr inbounds ({ [7 x ptr] }, ptr @_ZTV1B, i32 0, i32 0, i32 3)),
Expand Down
64 changes: 32 additions & 32 deletions clang/test/CodeGenCXX/rtti-linkage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,73 +3,73 @@

#include <typeinfo>

// CHECK-BOTH: _ZTIP1C = internal constant
// CHECK-BOTH: _ZTSP1C = internal constant
// CHECK-BOTH: _ZTS1C = internal constant
// CHECK-BOTH: _ZTI1C = internal constant
// CHECK-BOTH: _ZTIP1C = internal constant
// CHECK-BOTH: _ZTSPP1C = internal constant
// CHECK-BOTH: _ZTS1C = internal constant
// CHECK-BOTH: _ZTIPP1C = internal constant
// CHECK-BOTH: _ZTSM1Ci = internal constant
// CHECK-BOTH: _ZTSPP1C = internal constant
// CHECK-BOTH: _ZTIM1Ci = internal constant
// CHECK-BOTH: _ZTSPM1Ci = internal constant
// CHECK-BOTH: _ZTSM1Ci = internal constant
// CHECK-BOTH: _ZTIPM1Ci = internal constant
// CHECK-BOTH: _ZTSM1CS_ = internal constant
// CHECK-BOTH: _ZTSPM1Ci = internal constant
// CHECK-BOTH: _ZTIM1CS_ = internal constant
// CHECK-BOTH: _ZTSM1CPS_ = internal constant
// CHECK-BOTH: _ZTSM1CS_ = internal constant
// CHECK-BOTH: _ZTIM1CPS_ = internal constant
// CHECK-BOTH: _ZTSM1CPS_ = internal constant
// CHECK-BOTH: _ZTIM1A1C = internal constant
// CHECK-BOTH: _ZTSM1A1C = internal constant
// CHECK: _ZTS1A = linkonce_odr constant
// CHECK-WITH-HIDDEN: _ZTS1A = linkonce_odr hidden constant
// CHECK: _ZTI1A = linkonce_odr constant
// CHECK-WITH-HIDDEN: _ZTI1A = linkonce_odr hidden constant
// CHECK-BOTH: _ZTIM1A1C = internal constant
// CHECK-BOTH: _ZTSM1AP1C = internal constant
// CHECK: _ZTS1A = linkonce_odr constant
// CHECK-WITH-HIDDEN: _ZTS1A = linkonce_odr hidden constant
// CHECK-BOTH: _ZTIM1AP1C = internal constant
// CHECK-BOTH: _ZTSM1AP1C = internal constant

// CHECK-WITH-HIDDEN: _ZTSFN12_GLOBAL__N_11DEvE = internal constant
// CHECK-WITH-HIDDEN: @_ZTSPK2T4 = linkonce_odr hidden constant
// CHECK-WITH-HIDDEN: @_ZTS2T4 = linkonce_odr hidden constant
// CHECK-WITH-HIDDEN: @_ZTI2T4 = linkonce_odr hidden constant
// CHECK-WITH-HIDDEN: @_ZTIPK2T4 = linkonce_odr hidden constant
// CHECK-WITH-HIDDEN: @_ZTSZ2t5vE1A = internal constant
// CHECK-WITH-HIDDEN: @_ZTIPK2T4 = linkonce_odr hidden constant
// CHECK-WITH-HIDDEN: @_ZTSPK2T4 = linkonce_odr hidden constant
// CHECK-WITH-HIDDEN: @_ZTI2T4 = linkonce_odr hidden constant
// CHECK-WITH-HIDDEN: @_ZTS2T4 = linkonce_odr hidden constant
// CHECK-WITH-HIDDEN: @_ZTIZ2t5vE1A = internal constant
// CHECK-WITH-HIDDEN: @_ZTSZ2t6vE1A = linkonce_odr hidden constant
// CHECK-WITH-HIDDEN: @_ZTSZ2t5vE1A = internal constant
// CHECK-WITH-HIDDEN: @_ZTIZ2t6vE1A = linkonce_odr hidden constant
// CHECK-WITH-HIDDEN: @_ZTSZ2t6vE1A = linkonce_odr hidden constant
// CHECK-WITH-HIDDEN: @_ZTIPZ2t7vE1A = linkonce_odr hidden constant
// CHECK-WITH-HIDDEN: @_ZTSPZ2t7vE1A = linkonce_odr hidden constant
// CHECK-WITH-HIDDEN: @_ZTSZ2t7vE1A = linkonce_odr hidden constant
// CHECK-WITH-HIDDEN: @_ZTIZ2t7vE1A = linkonce_odr hidden constant
// CHECK-WITH-HIDDEN: @_ZTIPZ2t7vE1A = linkonce_odr hidden constant
// CHECK-WITH-HIDDEN: @_ZTSZ2t7vE1A = linkonce_odr hidden constant

// CHECK: _ZTSN12_GLOBAL__N_11DE = internal constant
// CHECK: _ZTIN12_GLOBAL__N_11DE = internal constant
// CHECK: _ZTSPN12_GLOBAL__N_11DE = internal constant
// CHECK: _ZTSN12_GLOBAL__N_11DE = internal constant
// CHECK: _ZTIPN12_GLOBAL__N_11DE = internal constant
// CHECK: _ZTSFN12_GLOBAL__N_11DEvE = internal constant
// CHECK: _ZTSPN12_GLOBAL__N_11DE = internal constant
// CHECK: _ZTIFN12_GLOBAL__N_11DEvE = internal constant
// CHECK: _ZTSFvN12_GLOBAL__N_11DEE = internal constant
// CHECK: _ZTSFN12_GLOBAL__N_11DEvE = internal constant
// CHECK: _ZTIFvN12_GLOBAL__N_11DEE = internal constant
// CHECK: _ZTSFvN12_GLOBAL__N_11DEE = internal constant
// CHECK: _ZTIPFvvE = linkonce_odr constant
// CHECK: _ZTSPFvvE = linkonce_odr constant
// CHECK: _ZTSFvvE = linkonce_odr constant
// CHECK: _ZTIFvvE = linkonce_odr constant
// CHECK: _ZTIPFvvE = linkonce_odr constant
// CHECK: _ZTSN12_GLOBAL__N_11EE = internal constant
// CHECK: _ZTSFvvE = linkonce_odr constant
// CHECK: _ZTIN12_GLOBAL__N_11EE = internal constant
// CHECK: _ZTSA10_i = linkonce_odr constant
// CHECK: _ZTSN12_GLOBAL__N_11EE = internal constant
// CHECK: _ZTIA10_i = linkonce_odr constant
// CHECK: _ZTSA10_i = linkonce_odr constant
// CHECK: _ZTI1TILj0EE = linkonce_odr constant
// CHECK: _ZTI1TILj1EE = weak_odr constant
// CHECK: _ZTI1TILj2EE = external constant
// CHECK: _ZTSZ2t5vE1A = internal constant
// CHECK: _ZTIZ2t5vE1A = internal constant
// CHECK: _ZTS1B ={{.*}} constant
// CHECK: _ZTSZ2t5vE1A = internal constant
// CHECK: _ZTI1B ={{.*}} constant
// CHECK: _ZTS1B ={{.*}} constant
// CHECK: _ZTS1F = linkonce_odr constant
// CHECK: _ZTSZ2t6vE1A = linkonce_odr constant
// CHECK: _ZTIZ2t6vE1A = linkonce_odr constant
// CHECK: _ZTSZ2t6vE1A = linkonce_odr constant
// CHECK: _ZTIPZ2t7vE1A = linkonce_odr constant
// CHECK: _ZTSPZ2t7vE1A = linkonce_odr constant
// CHECK: _ZTSZ2t7vE1A = linkonce_odr constant
// CHECK: _ZTIZ2t7vE1A = linkonce_odr constant
// CHECK: _ZTIPZ2t7vE1A = linkonce_odr constant
// CHECK: _ZTSZ2t7vE1A = linkonce_odr constant

// CHECK: _ZTIN12_GLOBAL__N_11DE

Expand Down
6 changes: 3 additions & 3 deletions clang/test/CodeGenCXX/rtti-visibility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

namespace Test1 {
// A is explicitly marked hidden, so all RTTI data should also be marked hidden.
// CHECK-TEST1: @_ZTSN5Test11AE = linkonce_odr hidden constant
// CHECK-TEST1: @_ZTIN5Test11AE = linkonce_odr hidden constant
// CHECK-TEST1: @_ZTSPN5Test11AE = linkonce_odr hidden constant
// CHECK-TEST1: @_ZTSN5Test11AE = linkonce_odr hidden constant
// CHECK-TEST1: @_ZTIPN5Test11AE = linkonce_odr hidden constant
// CHECK-TEST1: @_ZTSPN5Test11AE = linkonce_odr hidden constant
struct __attribute__((visibility("hidden"))) A { };

void f() {
Expand All @@ -20,8 +20,8 @@ namespace Test1 {

namespace Test2 {
// A is weak, so its linkage should be linkoce_odr, but not marked hidden.
// CHECK-TEST2: @_ZTSN5Test21AE = linkonce_odr constant
// CHECK-TEST2: @_ZTIN5Test21AE = linkonce_odr constant
// CHECK-TEST2: @_ZTSN5Test21AE = linkonce_odr constant
struct A { };
void f() {
(void)typeid(A);
Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenCXX/symbol-partition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

// CHECK: @gv = {{.*}}, partition "foo"
// CHECK: @_ZTV1S = {{.*}}, partition "foo"
// CHECK: @_ZTS1S = {{.*}}, partition "foo"
// CHECK: @_ZTI1S = {{.*}}, partition "foo"
// CHECK: @_ZTS1S = {{.*}}, partition "foo"

// CHECK: @_Z5ifuncv = {{.*}}, partition "foo"

Expand Down
Loading