12 changes: 5 additions & 7 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -3358,18 +3358,16 @@ def DiagnoseIf : InheritableAttr {
let Spellings = [GNU<"diagnose_if">];
let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty]>;
let Args = [ExprArgument<"Cond">, StringArgument<"Message">,
EnumArgument<"DiagnosticType", "DiagnosticType",
EnumArgument<"DefaultSeverity",
"DefaultSeverity",
/*is_string=*/true,
["error", "warning"],
["DT_Error", "DT_Warning"]>,
["error", "warning"],
["DS_error", "DS_warning"]>,
StringArgument<"WarningGroup", /*optional*/ 1>,
BoolArgument<"ArgDependent", 0, /*fake*/ 1>,
DeclArgument<Named, "Parent", 0, /*fake*/ 1>];
let InheritEvenIfAlreadyPresent = 1;
let LateParsed = LateAttrParseStandard;
let AdditionalMembers = [{
bool isError() const { return diagnosticType == DT_Error; }
bool isWarning() const { return diagnosticType == DT_Warning; }
}];
let TemplateDependent = 1;
let Documentation = [DiagnoseIfDocs];
}
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -6849,7 +6849,7 @@ def UnsafeBufferUsageDocs : Documentation {
The attribute ``[[clang::unsafe_buffer_usage]]`` should be placed on functions
that need to be avoided as they are prone to buffer overflows or unsafe buffer
struct fields. It is designed to work together with the off-by-default compiler
warning ``-Wunsafe-buffer-usage``to help codebases transition away from raw pointer
warning ``-Wunsafe-buffer-usage`` to help codebases transition away from raw pointer
based buffer management, in favor of safer abstractions such as C++20 ``std::span``.
The attribute causes ``-Wunsafe-buffer-usage`` to warn on every use of the function or
the field it is attached to, and it may also lead to emission of automatic fix-it
Expand Down
8 changes: 6 additions & 2 deletions clang/include/clang/Basic/Diagnostic.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,10 +336,12 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
// Map extensions to warnings or errors?
diag::Severity ExtBehavior = diag::Severity::Ignored;

DiagState()
DiagnosticIDs &DiagIDs;

DiagState(DiagnosticIDs &DiagIDs)
: IgnoreAllWarnings(false), EnableAllWarnings(false),
WarningsAsErrors(false), ErrorsAsFatal(false),
SuppressSystemWarnings(false) {}
SuppressSystemWarnings(false), DiagIDs(DiagIDs) {}

using iterator = llvm::DenseMap<unsigned, DiagnosticMapping>::iterator;
using const_iterator =
Expand Down Expand Up @@ -870,6 +872,8 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
/// \param FormatString A fixed diagnostic format string that will be hashed
/// and mapped to a unique DiagID.
template <unsigned N>
// TODO: Deprecate this once all uses are removed from LLVM
// [[deprecated("Use a CustomDiagDesc instead of a Level")]]
unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) {
return Diags->getCustomDiagID((DiagnosticIDs::Level)L,
StringRef(FormatString, N - 1));
Expand Down
5 changes: 3 additions & 2 deletions clang/include/clang/Basic/DiagnosticCategories.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ namespace clang {
};

enum class Group {
#define DIAG_ENTRY(GroupName, FlagNameOffset, Members, SubGroups, Docs) \
GroupName,
#define DIAG_ENTRY(GroupName, FlagNameOffset, Members, SubGroups, Docs) \
GroupName,
#include "clang/Basic/DiagnosticGroups.inc"
#undef CATEGORY
#undef DIAG_ENTRY
NUM_GROUPS
};
} // end namespace diag
} // end namespace clang
Expand Down
155 changes: 137 additions & 18 deletions clang/include/clang/Basic/DiagnosticIDs.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@
#ifndef LLVM_CLANG_BASIC_DIAGNOSTICIDS_H
#define LLVM_CLANG_BASIC_DIAGNOSTICIDS_H

#include "clang/Basic/DiagnosticCategories.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
#include <optional>
#include <vector>

Expand Down Expand Up @@ -82,7 +84,7 @@ namespace clang {
/// to either Ignore (nothing), Remark (emit a remark), Warning
/// (emit a warning) or Error (emit as an error). It allows clients to
/// map ERRORs to Error or Fatal (stop emitting diagnostics after this one).
enum class Severity {
enum class Severity : uint8_t {
// NOTE: 0 means "uncomputed".
Ignored = 1, ///< Do not present this diagnostic, ignore it.
Remark = 2, ///< Present this diagnostic as a remark.
Expand Down Expand Up @@ -179,13 +181,96 @@ class DiagnosticMapping {
class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> {
public:
/// The level of the diagnostic, after it has been through mapping.
enum Level {
Ignored, Note, Remark, Warning, Error, Fatal
enum Level : uint8_t { Ignored, Note, Remark, Warning, Error, Fatal };

// Diagnostic classes.
enum Class {
CLASS_INVALID = 0x00,
CLASS_NOTE = 0x01,
CLASS_REMARK = 0x02,
CLASS_WARNING = 0x03,
CLASS_EXTENSION = 0x04,
CLASS_ERROR = 0x05
};

static bool IsCustomDiag(diag::kind Diag) {
return Diag >= diag::DIAG_UPPER_LIMIT;
}

class CustomDiagDesc {
LLVM_PREFERRED_TYPE(diag::Severity)
unsigned DefaultSeverity : 3;
LLVM_PREFERRED_TYPE(Class)
unsigned DiagClass : 3;
LLVM_PREFERRED_TYPE(bool)
unsigned ShowInSystemHeader : 1;
LLVM_PREFERRED_TYPE(bool)
unsigned ShowInSystemMacro : 1;
LLVM_PREFERRED_TYPE(bool)
unsigned HasGroup : 1;
diag::Group Group;
std::string Description;

auto get_as_tuple() const {
return std::tuple(DefaultSeverity, DiagClass, ShowInSystemHeader,
ShowInSystemMacro, HasGroup, Group,
std::string_view{Description});
}

public:
CustomDiagDesc(diag::Severity DefaultSeverity, std::string Description,
unsigned Class = CLASS_WARNING,
bool ShowInSystemHeader = false,
bool ShowInSystemMacro = false,
std::optional<diag::Group> Group = std::nullopt)
: DefaultSeverity(static_cast<unsigned>(DefaultSeverity)),
DiagClass(Class), ShowInSystemHeader(ShowInSystemHeader),
ShowInSystemMacro(ShowInSystemMacro), HasGroup(Group != std::nullopt),
Group(Group.value_or(diag::Group{})),
Description(std::move(Description)) {}

std::optional<diag::Group> GetGroup() const {
if (HasGroup)
return Group;
return std::nullopt;
}

diag::Severity GetDefaultSeverity() const {
return static_cast<diag::Severity>(DefaultSeverity);
}

Class GetClass() const { return static_cast<Class>(DiagClass); }
std::string_view GetDescription() const { return Description; }
bool ShouldShowInSystemHeader() const { return ShowInSystemHeader; }

friend bool operator==(const CustomDiagDesc &lhs,
const CustomDiagDesc &rhs) {
return lhs.get_as_tuple() == rhs.get_as_tuple();
}

friend bool operator<(const CustomDiagDesc &lhs,
const CustomDiagDesc &rhs) {
return lhs.get_as_tuple() < rhs.get_as_tuple();
}
};

struct GroupInfo {
LLVM_PREFERRED_TYPE(diag::Severity)
unsigned Severity : 3;
LLVM_PREFERRED_TYPE(bool)
unsigned HasNoWarningAsError : 1;
};

private:
/// Information for uniquing and looking up custom diags.
std::unique_ptr<diag::CustomDiagInfo> CustomDiagInfo;
std::unique_ptr<GroupInfo[]> GroupInfos = []() {
auto GIs = std::make_unique<GroupInfo[]>(
static_cast<size_t>(diag::Group::NUM_GROUPS));
for (size_t i = 0; i != static_cast<size_t>(diag::Group::NUM_GROUPS); ++i)
GIs[i] = {{}, false};
return GIs;
}();

public:
DiagnosticIDs();
Expand All @@ -200,7 +285,35 @@ class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> {
// FIXME: Replace this function with a create-only facilty like
// createCustomDiagIDFromFormatString() to enforce safe usage. At the time of
// writing, nearly all callers of this function were invalid.
unsigned getCustomDiagID(Level L, StringRef FormatString);
unsigned getCustomDiagID(CustomDiagDesc Diag);

// TODO: Deprecate this once all uses are removed from LLVM
// [[deprecated("Use a CustomDiagDesc instead of a Level")]]
unsigned getCustomDiagID(Level Level, StringRef Message) {
return getCustomDiagID([&]() -> CustomDiagDesc {
switch (Level) {
case DiagnosticIDs::Level::Ignored:
return {diag::Severity::Ignored, std::string(Message), CLASS_WARNING,
/*ShowInSystemHeader*/ true};
case DiagnosticIDs::Level::Note:
return {diag::Severity::Fatal, std::string(Message), CLASS_NOTE,
/*ShowInSystemHeader*/ true};
case DiagnosticIDs::Level::Remark:
return {diag::Severity::Remark, std::string(Message), CLASS_REMARK,
/*ShowInSystemHeader*/ true};
case DiagnosticIDs::Level::Warning:
return {diag::Severity::Warning, std::string(Message), CLASS_WARNING,
/*ShowInSystemHeader*/ true};
case DiagnosticIDs::Level::Error:
return {diag::Severity::Error, std::string(Message), CLASS_ERROR,
/*ShowInSystemHeader*/ true};
case DiagnosticIDs::Level::Fatal:
return {diag::Severity::Fatal, std::string(Message), CLASS_ERROR,
/*ShowInSystemHeader*/ true};
}
llvm_unreachable("Fully covered switch above!");
}());
}

//===--------------------------------------------------------------------===//
// Diagnostic classification and reporting interfaces.
Expand All @@ -212,35 +325,36 @@ class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> {
/// Return true if the unmapped diagnostic levelof the specified
/// diagnostic ID is a Warning or Extension.
///
/// This only works on builtin diagnostics, not custom ones, and is not
/// legal to call on NOTEs.
static bool isBuiltinWarningOrExtension(unsigned DiagID);
/// This is not legal to call on NOTEs.
bool isWarningOrExtension(unsigned DiagID) const;

/// Return true if the specified diagnostic is mapped to errors by
/// default.
static bool isDefaultMappingAsError(unsigned DiagID);
bool isDefaultMappingAsError(unsigned DiagID) const;

/// Get the default mapping for this diagnostic.
static DiagnosticMapping getDefaultMapping(unsigned DiagID);
DiagnosticMapping getDefaultMapping(unsigned DiagID) const;

void initCustomDiagMapping(DiagnosticMapping &, unsigned DiagID);

/// Determine whether the given built-in diagnostic ID is a Note.
static bool isBuiltinNote(unsigned DiagID);
/// Determine whether the given diagnostic ID is a Note.
bool isNote(unsigned DiagID) const;

/// Determine whether the given built-in diagnostic ID is for an
/// Determine whether the given diagnostic ID is for an
/// extension of some sort.
static bool isBuiltinExtensionDiag(unsigned DiagID) {
bool isExtensionDiag(unsigned DiagID) const {
bool ignored;
return isBuiltinExtensionDiag(DiagID, ignored);
return isExtensionDiag(DiagID, ignored);
}

/// Determine whether the given built-in diagnostic ID is for an
/// Determine whether the given diagnostic ID is for an
/// extension of some sort, and whether it is enabled by default.
///
/// This also returns EnabledByDefault, which is set to indicate whether the
/// diagnostic is ignored by default (in which case -pedantic enables it) or
/// treated as a warning/error by default.
///
static bool isBuiltinExtensionDiag(unsigned DiagID, bool &EnabledByDefault);
bool isExtensionDiag(unsigned DiagID, bool &EnabledByDefault) const;

/// Given a group ID, returns the flag that toggles the group.
/// For example, for Group::DeprecatedDeclarations, returns
Expand All @@ -250,19 +364,22 @@ class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> {
/// Given a diagnostic group ID, return its documentation.
static StringRef getWarningOptionDocumentation(diag::Group GroupID);

void setGroupSeverity(StringRef Group, diag::Severity);
void setGroupNoWarningsAsError(StringRef Group, bool);

/// Given a group ID, returns the flag that toggles the group.
/// For example, for "deprecated-declarations", returns
/// Group::DeprecatedDeclarations.
static std::optional<diag::Group> getGroupForWarningOption(StringRef);

/// Return the lowest-level group that contains the specified diagnostic.
static std::optional<diag::Group> getGroupForDiag(unsigned DiagID);
std::optional<diag::Group> getGroupForDiag(unsigned DiagID) const;

/// Return the lowest-level warning option that enables the specified
/// diagnostic.
///
/// If there is no -Wfoo flag that controls the diagnostic, this returns null.
static StringRef getWarningOptionForDiag(unsigned DiagID);
StringRef getWarningOptionForDiag(unsigned DiagID);

/// Return the category number that a specified \p DiagID belongs to,
/// or 0 if no category.
Expand Down Expand Up @@ -363,6 +480,8 @@ class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> {
getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc,
const DiagnosticsEngine &Diag) const LLVM_READONLY;

Class getDiagClass(unsigned DiagID) const;

/// Used to report a diagnostic that is finally fully formed.
///
/// \returns \c true if the diagnostic was emitted, \c false if it was
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/DiagnosticLexKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,8 @@ def note_macro_expansion_here : Note<"expansion of macro %0 requested here">;

def ext_pp_opencl_variadic_macros : Extension<
"variadic macros are a Clang extension in OpenCL">;
def err_opencl_logical_exclusive_or : Error<
"^^ is a reserved operator in OpenCL">;

def ext_pp_gnu_line_directive : Extension<
"this style of line directive is a GNU extension">,
Expand Down
2 changes: 0 additions & 2 deletions clang/include/clang/Basic/DiagnosticParseKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -1397,8 +1397,6 @@ def err_modifier_expected_colon : Error<"missing ':' after %0 modifier">;
// OpenCL errors.
def err_opencl_taking_function_address_parser : Error<
"taking address of function is not allowed">;
def err_opencl_logical_exclusive_or : Error<
"^^ is a reserved operator in OpenCL">;

// C++ for OpenCL.
def err_openclcxx_virtual_function : Error<
Expand Down
10 changes: 10 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,10 @@ def warn_deprecated_literal_operator_id: Warning<
"is deprecated">, InGroup<DeprecatedLiteralOperator>, DefaultIgnore;
def warn_reserved_module_name : Warning<
"%0 is a reserved name for a module">, InGroup<ReservedModuleIdentifier>;
def warn_import_implementation_partition_unit_in_interface_unit : Warning<
"importing an implementation partition unit in a module interface is not recommended. "
"Names from %0 may not be reachable">,
InGroup<DiagGroup<"import-implementation-partition-unit-in-interface-unit">>;

def warn_parameter_size: Warning<
"%0 is a large (%1 bytes) pass-by-value argument; "
Expand Down Expand Up @@ -2929,9 +2933,15 @@ def ext_constexpr_function_never_constant_expr : ExtWarn<
"constant expression">, InGroup<DiagGroup<"invalid-constexpr">>, DefaultError;
def err_attr_cond_never_constant_expr : Error<
"%0 attribute expression never produces a constant expression">;
def err_diagnose_if_unknown_warning : Error<"unknown warning group '%0'">;
def err_diagnose_if_invalid_diagnostic_type : Error<
"invalid diagnostic type for 'diagnose_if'; use \"error\" or \"warning\" "
"instead">;
def err_diagnose_if_unknown_option : Error<"unknown diagnostic option">;
def err_diagnose_if_expected_equals : Error<
"expected '=' after diagnostic option">;
def err_diagnose_if_unexpected_value : Error<
"unexpected value; use 'true' or 'false'">;
def err_constexpr_body_no_return : Error<
"no return statement in %select{constexpr|consteval}0 function">;
def err_constexpr_return_missing_expr : Error<
Expand Down
3 changes: 0 additions & 3 deletions clang/include/clang/Basic/TokenKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -255,9 +255,6 @@ PUNCTUATOR(at, "@")
PUNCTUATOR(lesslessless, "<<<")
PUNCTUATOR(greatergreatergreater, ">>>")

// CL support
PUNCTUATOR(caretcaret, "^^")

// C99 6.4.1: Keywords. These turn into kw_* tokens.
// Flags allowed:
// KEYALL - This is a keyword in all variants of C and C++, or it
Expand Down
12 changes: 12 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1894,6 +1894,18 @@ def fprofile_selected_function_group :
Visibility<[ClangOption, CC1Option]>, MetaVarName<"<i>">,
HelpText<"Partition functions into N groups using -fprofile-function-groups and select only functions in group i to be instrumented. The valid range is 0 to N-1 inclusive">,
MarshallingInfoInt<CodeGenOpts<"ProfileSelectedFunctionGroup">>;
def fcodegen_data_generate_EQ : Joined<["-"], "fcodegen-data-generate=">,
Group<f_Group>, Visibility<[ClangOption, CLOption]>, MetaVarName<"<path>">,
HelpText<"Emit codegen data into the object file. LLD for MachO (currently) merges them into the specified <path>.">;
def fcodegen_data_generate : Flag<["-"], "fcodegen-data-generate">,
Group<f_Group>, Visibility<[ClangOption, CLOption]>, Alias<fcodegen_data_generate_EQ>, AliasArgs<["default.cgdata"]>,
HelpText<"Emit codegen data into the object file. LLD for MachO (currently) merges them into default.cgdata.">;
def fcodegen_data_use_EQ : Joined<["-"], "fcodegen-data-use=">,
Group<f_Group>, Visibility<[ClangOption, CLOption]>, MetaVarName<"<path>">,
HelpText<"Use codegen data read from the specified <path>.">;
def fcodegen_data_use : Flag<["-"], "fcodegen-data-use">,
Group<f_Group>, Visibility<[ClangOption, CLOption]>, Alias<fcodegen_data_use_EQ>, AliasArgs<["default.cgdata"]>,
HelpText<"Use codegen data read from default.cgdata to optimize the binary">;
def fswift_async_fp_EQ : Joined<["-"], "fswift-async-fp=">,
Group<f_Group>,
Visibility<[ClangOption, CC1Option, CC1AsOption, CLOption]>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ DefinedOrUnknownSVal getDynamicElementCount(ProgramStateRef State,

/// Set the dynamic extent \p Extent of the region \p MR.
ProgramStateRef setDynamicExtent(ProgramStateRef State, const MemRegion *MR,
DefinedOrUnknownSVal Extent, SValBuilder &SVB);
DefinedOrUnknownSVal Extent);

/// Get the dynamic extent for a symbolic value that represents a buffer. If
/// there is an offsetting to the underlying buffer we consider that too.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,17 +215,17 @@ class SValBuilder {
/// Conjure a symbol representing heap allocated memory region.
///
/// Note, the expression should represent a location.
DefinedOrUnknownSVal getConjuredHeapSymbolVal(const Expr *E,
const LocationContext *LCtx,
unsigned Count);
DefinedSVal getConjuredHeapSymbolVal(const Expr *E,
const LocationContext *LCtx,
unsigned Count);

/// Conjure a symbol representing heap allocated memory region.
///
/// Note, now, the expression *doesn't* need to represent a location.
/// But the type need to!
DefinedOrUnknownSVal getConjuredHeapSymbolVal(const Expr *E,
const LocationContext *LCtx,
QualType type, unsigned Count);
DefinedSVal getConjuredHeapSymbolVal(const Expr *E,
const LocationContext *LCtx,
QualType type, unsigned Count);

/// Create an SVal representing the result of an alloca()-like call, that is,
/// an AllocaRegion on the stack.
Expand Down
1 change: 0 additions & 1 deletion clang/lib/AST/APValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -947,7 +947,6 @@ std::string APValue::getAsString(const ASTContext &Ctx, QualType Ty) const {
std::string Result;
llvm::raw_string_ostream Out(Result);
printPretty(Out, Ctx, Ty);
Out.flush();
return Result;
}

Expand Down
38 changes: 33 additions & 5 deletions clang/lib/AST/ByteCode/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2638,18 +2638,46 @@ bool Compiler<Emitter>::VisitCXXReinterpretCastExpr(
const CXXReinterpretCastExpr *E) {
const Expr *SubExpr = E->getSubExpr();

bool Fatal = false;
std::optional<PrimType> FromT = classify(SubExpr);
std::optional<PrimType> ToT = classify(E);

if (!FromT || !ToT)
Fatal = true;
else
Fatal = (ToT != FromT);
return this->emitInvalidCast(CastKind::Reinterpret, /*Fatal=*/true, E);

if (FromT == PT_Ptr || ToT == PT_Ptr) {
// Both types could be PT_Ptr because their expressions are glvalues.
std::optional<PrimType> PointeeFromT;
if (SubExpr->getType()->isPointerOrReferenceType())
PointeeFromT = classify(SubExpr->getType()->getPointeeType());
else
PointeeFromT = classify(SubExpr->getType());

std::optional<PrimType> PointeeToT;
if (E->getType()->isPointerOrReferenceType())
PointeeToT = classify(E->getType()->getPointeeType());
else
PointeeToT = classify(E->getType());

bool Fatal = true;
if (PointeeToT && PointeeFromT) {
if (isIntegralType(*PointeeFromT) && isIntegralType(*PointeeToT))
Fatal = false;
}

if (!this->emitInvalidCast(CastKind::Reinterpret, Fatal, E))
return false;

if (E->getCastKind() == CK_LValueBitCast)
return this->delegate(SubExpr);
return this->VisitCastExpr(E);
}

// Try to actually do the cast.
bool Fatal = (ToT != FromT);
if (!this->emitInvalidCast(CastKind::Reinterpret, Fatal, E))
return false;

return this->delegate(SubExpr);
return this->VisitCastExpr(E);
}

template <class Emitter>
Expand Down
2 changes: 0 additions & 2 deletions clang/lib/AST/DeclPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,6 @@ static void printExplicitSpecifier(ExplicitSpecifier ES, llvm::raw_ostream &Out,
EOut << ")";
}
EOut << " ";
EOut.flush();
Out << Proto;
}

Expand Down Expand Up @@ -790,7 +789,6 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
llvm::raw_string_ostream EOut(Proto);
FT->getNoexceptExpr()->printPretty(EOut, nullptr, SubPolicy,
Indentation, "\n", &Context);
EOut.flush();
Proto += ")";
}
}
Expand Down
6 changes: 1 addition & 5 deletions clang/lib/AST/Expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ std::string SYCLUniqueStableNameExpr::ComputeName(ASTContext &Context,
llvm::raw_string_ostream Out(Buffer);
Ctx->mangleCanonicalTypeName(Ty, Out);

return Out.str();
return Buffer;
}

PredefinedExpr::PredefinedExpr(SourceLocation L, QualType FNTy,
Expand Down Expand Up @@ -798,7 +798,6 @@ std::string PredefinedExpr::ComputeName(PredefinedIdentKind IK,
FD->printQualifiedName(POut, Policy);

if (IK == PredefinedIdentKind::Function) {
POut.flush();
Out << Proto;
return std::string(Name);
}
Expand Down Expand Up @@ -880,15 +879,12 @@ std::string PredefinedExpr::ComputeName(PredefinedIdentKind IK,
}
}

TOut.flush();
if (!TemplateParams.empty()) {
// remove the trailing comma and space
TemplateParams.resize(TemplateParams.size() - 2);
POut << " [" << TemplateParams << "]";
}

POut.flush();

// Print "auto" for all deduced return types. This includes C++1y return
// type deduction and lambdas. For trailing return types resolve the
// decltype expression. Otherwise print the real type when this is
Expand Down
8 changes: 4 additions & 4 deletions clang/lib/AST/Mangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -574,9 +574,9 @@ class ASTNameGenerator::Implementation {
std::string BackendBuf;
llvm::raw_string_ostream BOS(BackendBuf);

llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL);
llvm::Mangler::getNameWithPrefix(BOS, FrontendBuf, DL);

return BOS.str();
return BackendBuf;
}

std::string getMangledThunk(const CXXMethodDecl *MD, const ThunkInfo &T,
Expand All @@ -589,9 +589,9 @@ class ASTNameGenerator::Implementation {
std::string BackendBuf;
llvm::raw_string_ostream BOS(BackendBuf);

llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL);
llvm::Mangler::getNameWithPrefix(BOS, FrontendBuf, DL);

return BOS.str();
return BackendBuf;
}
};

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/MicrosoftMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1396,7 +1396,7 @@ void MicrosoftCXXNameMangler::mangleNestedName(GlobalDecl GD) {
Stream << '_' << Discriminator;
if (ParameterDiscriminator)
Stream << '_' << ParameterDiscriminator;
return Stream.str();
return Buffer;
};

unsigned Discriminator = BD->getBlockManglingNumber();
Expand Down
5 changes: 2 additions & 3 deletions clang/lib/AST/StmtViz.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,14 @@ struct DOTGraphTraits<const Stmt*> : public DefaultDOTGraphTraits {
static std::string getNodeLabel(const Stmt* Node, const Stmt* Graph) {

#ifndef NDEBUG
std::string OutSStr;
llvm::raw_string_ostream Out(OutSStr);
std::string OutStr;
llvm::raw_string_ostream Out(OutStr);

if (Node)
Out << Node->getStmtClassName();
else
Out << "<NULL>";

std::string OutStr = Out.str();
if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());

// Process string output to make it nicer...
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/ASTMatchers/Dynamic/Registry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -791,7 +791,7 @@ Registry::getMatcherCompletions(ArrayRef<ArgKind> AcceptedTypes) {
TypedText += "\"";
}

Completions.emplace_back(TypedText, OS.str(), MaxSpecificity);
Completions.emplace_back(TypedText, Decl, MaxSpecificity);
}
}

Expand Down
7 changes: 3 additions & 4 deletions clang/lib/Analysis/CFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6164,7 +6164,7 @@ void CFGBlock::printTerminatorJson(raw_ostream &Out, const LangOptions &LO,

printTerminator(TempOut, LO);

Out << JsonFormat(TempOut.str(), AddQuotes);
Out << JsonFormat(Buf, AddQuotes);
}

// Returns true if by simply looking at the block, we can be sure that it
Expand Down Expand Up @@ -6345,10 +6345,9 @@ struct DOTGraphTraits<const CFG*> : public DefaultDOTGraphTraits {
DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}

static std::string getNodeLabel(const CFGBlock *Node, const CFG *Graph) {
std::string OutSStr;
llvm::raw_string_ostream Out(OutSStr);
std::string OutStr;
llvm::raw_string_ostream Out(OutStr);
print_block(Out,Graph, *Node, *GraphHelper, false, false);
std::string& OutStr = Out.str();

if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());

Expand Down
22 changes: 14 additions & 8 deletions clang/lib/Basic/Diagnostic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ void DiagnosticsEngine::Reset(bool soft /*=false*/) {

// Create a DiagState and DiagStatePoint representing diagnostic changes
// through command-line.
DiagStates.emplace_back();
DiagStates.emplace_back(*Diags);
DiagStatesByLoc.appendFirst(&DiagStates.back());
}
}
Expand Down Expand Up @@ -166,8 +166,11 @@ DiagnosticsEngine::DiagState::getOrAddMapping(diag::kind Diag) {
DiagMap.insert(std::make_pair(Diag, DiagnosticMapping()));

// Initialize the entry if we added it.
if (Result.second)
Result.first->second = DiagnosticIDs::getDefaultMapping(Diag);
if (Result.second) {
Result.first->second = DiagIDs.getDefaultMapping(Diag);
if (DiagnosticIDs::IsCustomDiag(Diag))
DiagIDs.initCustomDiagMapping(Result.first->second, Diag);
}

return Result.first->second;
}
Expand Down Expand Up @@ -309,7 +312,8 @@ void DiagnosticsEngine::DiagStateMap::dump(SourceManager &SrcMgr,

for (auto &Mapping : *Transition.State) {
StringRef Option =
DiagnosticIDs::getWarningOptionForDiag(Mapping.first);
SrcMgr.getDiagnostics().Diags->getWarningOptionForDiag(
Mapping.first);
if (!DiagName.empty() && DiagName != Option)
continue;

Expand Down Expand Up @@ -353,9 +357,7 @@ void DiagnosticsEngine::PushDiagStatePoint(DiagState *State,

void DiagnosticsEngine::setSeverity(diag::kind Diag, diag::Severity Map,
SourceLocation L) {
assert(Diag < diag::DIAG_UPPER_LIMIT &&
"Can only map builtin diagnostics");
assert((Diags->isBuiltinWarningOrExtension(Diag) ||
assert((Diags->isWarningOrExtension(Diag) ||
(Map == diag::Severity::Fatal || Map == diag::Severity::Error)) &&
"Cannot map errors into warnings!");
assert((L.isInvalid() || SourceMgr) && "No SourceMgr for valid location");
Expand Down Expand Up @@ -407,6 +409,8 @@ bool DiagnosticsEngine::setSeverityForGroup(diag::Flavor Flavor,
if (Diags->getDiagnosticsInGroup(Flavor, Group, GroupDiags))
return true;

Diags->setGroupSeverity(Group, Map);

// Set the mapping.
for (diag::kind Diag : GroupDiags)
setSeverity(Diag, Map, Loc);
Expand All @@ -429,6 +433,7 @@ bool DiagnosticsEngine::setDiagnosticGroupWarningAsError(StringRef Group,
if (Enabled)
return setSeverityForGroup(diag::Flavor::WarningOrError, Group,
diag::Severity::Error);
Diags->setGroupSeverity(Group, diag::Severity::Warning);

// Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and
// potentially downgrade anything already mapped to be a warning.
Expand Down Expand Up @@ -460,6 +465,7 @@ bool DiagnosticsEngine::setDiagnosticGroupErrorAsFatal(StringRef Group,
if (Enabled)
return setSeverityForGroup(diag::Flavor::WarningOrError, Group,
diag::Severity::Fatal);
Diags->setGroupSeverity(Group, diag::Severity::Error);

// Otherwise, we want to set the diagnostic mapping's "no Wfatal-errors" bit,
// and potentially downgrade anything already mapped to be a fatal error.
Expand Down Expand Up @@ -492,7 +498,7 @@ void DiagnosticsEngine::setSeverityForAll(diag::Flavor Flavor,

// Set the mapping.
for (diag::kind Diag : AllDiags)
if (Diags->isBuiltinWarningOrExtension(Diag))
if (Diags->isWarningOrExtension(Diag))
setSeverity(Diag, Map, Loc);
}

Expand Down
280 changes: 163 additions & 117 deletions clang/lib/Basic/DiagnosticIDs.cpp

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion clang/lib/Basic/OperatorPrecedence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator,
case tok::pipeequal: return prec::Assignment;
case tok::question: return prec::Conditional;
case tok::pipepipe: return prec::LogicalOr;
case tok::caretcaret:
case tok::ampamp: return prec::LogicalAnd;
case tok::pipe: return prec::InclusiveOr;
case tok::caret: return prec::ExclusiveOr;
Expand Down
41 changes: 38 additions & 3 deletions clang/lib/CodeGen/BackendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/ToolOutputFile.h"
Expand All @@ -64,7 +65,6 @@
#include "llvm/Transforms/IPO/LowerTypeTests.h"
#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
#include "llvm/Transforms/InstCombine/InstCombine.h"
#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"
#include "llvm/Transforms/Instrumentation/BoundsChecking.h"
Expand Down Expand Up @@ -322,6 +322,40 @@ static bool actionRequiresCodeGen(BackendAction Action) {
Action != Backend_EmitLL;
}

static std::string flattenClangCommandLine(ArrayRef<std::string> Args,
StringRef MainFilename) {
if (Args.empty())
return std::string{};

std::string FlatCmdLine;
raw_string_ostream OS(FlatCmdLine);
bool PrintedOneArg = false;
if (!StringRef(Args[0]).contains("-cc1")) {
llvm::sys::printArg(OS, "-cc1", /*Quote=*/true);
PrintedOneArg = true;
}
for (unsigned i = 0; i < Args.size(); i++) {
StringRef Arg = Args[i];
if (Arg.empty())
continue;
if (Arg == "-main-file-name" || Arg == "-o") {
i++; // Skip this argument and next one.
continue;
}
if (Arg.starts_with("-object-file-name") || Arg == MainFilename)
continue;
// Skip fmessage-length for reproducibility.
if (Arg.starts_with("-fmessage-length"))
continue;
if (PrintedOneArg)
OS << " ";
llvm::sys::printArg(OS, Arg, /*Quote=*/true);
PrintedOneArg = true;
}
OS.flush();
return FlatCmdLine;
}

static bool initTargetOptions(DiagnosticsEngine &Diags,
llvm::TargetOptions &Options,
const CodeGenOptions &CodeGenOpts,
Expand Down Expand Up @@ -484,8 +518,9 @@ static bool initTargetOptions(DiagnosticsEngine &Diags,
Entry.Group == frontend::IncludeDirGroup::System))
Options.MCOptions.IASSearchPaths.push_back(
Entry.IgnoreSysRoot ? Entry.Path : HSOpts.Sysroot + Entry.Path);
Options.MCOptions.Argv0 = CodeGenOpts.Argv0;
Options.MCOptions.CommandLineArgs = CodeGenOpts.CommandLineArgs;
Options.MCOptions.Argv0 = CodeGenOpts.Argv0 ? CodeGenOpts.Argv0 : "";
Options.MCOptions.CommandlineArgs = flattenClangCommandLine(
CodeGenOpts.CommandLineArgs, CodeGenOpts.MainFileName);
Options.MCOptions.AsSecureLogFile = CodeGenOpts.AsSecureLogFile;
Options.MCOptions.PPCUseFullRegisterNames =
CodeGenOpts.PPCUseFullRegisterNames;
Expand Down
7 changes: 1 addition & 6 deletions clang/lib/CodeGen/CGOpenMPRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7815,12 +7815,7 @@ class MappableExprsHandler {
const Expr *VarRef = nullptr, bool ForDeviceAddr = false) {
if (SkipVarSet.contains(D))
return;
auto It = Info.find(D);
if (It == Info.end())
It = Info
.insert(std::make_pair(
D, SmallVector<SmallVector<MapInfo, 8>, 4>(Total)))
.first;
auto It = Info.try_emplace(D, Total).first;
It->second[Kind].emplace_back(
L, MapType, MapModifiers, MotionModifiers, ReturnDevicePointer,
IsImplicit, Mapper, VarRef, ForDeviceAddr);
Expand Down
19 changes: 19 additions & 0 deletions clang/lib/Driver/ToolChains/CommonArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2753,6 +2753,25 @@ void tools::addMachineOutlinerArgs(const Driver &D,
addArg(Twine("-enable-machine-outliner=never"));
}
}

auto *CodeGenDataGenArg =
Args.getLastArg(options::OPT_fcodegen_data_generate_EQ);
auto *CodeGenDataUseArg = Args.getLastArg(options::OPT_fcodegen_data_use_EQ);

// We only allow one of them to be specified.
if (CodeGenDataGenArg && CodeGenDataUseArg)
D.Diag(diag::err_drv_argument_not_allowed_with)
<< CodeGenDataGenArg->getAsString(Args)
<< CodeGenDataUseArg->getAsString(Args);

// For codegen data gen, the output file is passed to the linker
// while a boolean flag is passed to the LLVM backend.
if (CodeGenDataGenArg)
addArg(Twine("-codegen-data-generate"));

// For codegen data use, the input file is passed to the LLVM backend.
if (CodeGenDataUseArg)
addArg(Twine("-codegen-data-use-path=") + CodeGenDataUseArg->getValue());
}

void tools::addOpenMPDeviceRTL(const Driver &D,
Expand Down
33 changes: 33 additions & 0 deletions clang/lib/Driver/ToolChains/Darwin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,13 @@ void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args,
llvm::sys::path::append(Path, "default.profdata");
CmdArgs.push_back(Args.MakeArgString(Twine("--cs-profile-path=") + Path));
}

auto *CodeGenDataGenArg =
Args.getLastArg(options::OPT_fcodegen_data_generate_EQ);
if (CodeGenDataGenArg)
CmdArgs.push_back(
Args.MakeArgString(Twine("--codegen-data-generate-path=") +
CodeGenDataGenArg->getValue()));
}
}

Expand Down Expand Up @@ -633,6 +640,32 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-mllvm");
CmdArgs.push_back("-enable-linkonceodr-outlining");

// Propagate codegen data flags to the linker for the LLVM backend.
auto *CodeGenDataGenArg =
Args.getLastArg(options::OPT_fcodegen_data_generate_EQ);
auto *CodeGenDataUseArg = Args.getLastArg(options::OPT_fcodegen_data_use_EQ);

// We only allow one of them to be specified.
const Driver &D = getToolChain().getDriver();
if (CodeGenDataGenArg && CodeGenDataUseArg)
D.Diag(diag::err_drv_argument_not_allowed_with)
<< CodeGenDataGenArg->getAsString(Args)
<< CodeGenDataUseArg->getAsString(Args);

// For codegen data gen, the output file is passed to the linker
// while a boolean flag is passed to the LLVM backend.
if (CodeGenDataGenArg) {
CmdArgs.push_back("-mllvm");
CmdArgs.push_back("-codegen-data-generate");
}

// For codegen data use, the input file is passed to the LLVM backend.
if (CodeGenDataUseArg) {
CmdArgs.push_back("-mllvm");
CmdArgs.push_back(Args.MakeArgString(Twine("-codegen-data-use-path=") +
CodeGenDataUseArg->getValue()));
}

// Setup statistics file output.
SmallString<128> StatsFile =
getStatsFileName(Args, Output, Inputs[0], getToolChain().getDriver());
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/Format/MacroExpander.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,10 @@ MacroExpander::expand(FormatToken *ID,
auto expandArgument = [&](FormatToken *Tok) -> bool {
// If the current token references a parameter, expand the corresponding
// argument.
if (Tok->isNot(tok::identifier) || ExpandedArgs.contains(Tok->TokenText))
if (Tok->isNot(tok::identifier))
return false;
if (!ExpandedArgs.insert(Tok->TokenText).second)
return false;
ExpandedArgs.insert(Tok->TokenText);
auto I = Def.ArgMap.find(Tok->TokenText);
if (I == Def.ArgMap.end())
return false;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Format/UnwrappedLineParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4042,7 +4042,7 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
}

auto IsListInitialization = [&] {
if (!ClassName || IsDerived)
if (!ClassName || IsDerived || JSPastExtendsOrImplements)
return false;
assert(FormatTok->is(tok::l_brace));
const auto *Prev = FormatTok->getPreviousNonComment();
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Frontend/LogDiagnosticPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ void LogDiagnosticPrinter::HandleDiagnostic(DiagnosticsEngine::Level Level,
DE.DiagnosticLevel = Level;

DE.WarningOption =
std::string(DiagnosticIDs::getWarningOptionForDiag(DE.DiagnosticID));
std::string(Info.getDiags()->getDiagnosticIDs()->getWarningOptionForDiag(
DE.DiagnosticID));

// Format the message.
SmallString<100> MessageStr;
Expand Down Expand Up @@ -160,4 +161,3 @@ void LogDiagnosticPrinter::HandleDiagnostic(DiagnosticsEngine::Level Level,
// Record the diagnostic entry.
Entries.push_back(DE);
}

3 changes: 1 addition & 2 deletions clang/lib/Frontend/Rewrite/RewriteObjC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4111,9 +4111,8 @@ void RewriteObjC::RewriteBlockPointerDecl(NamedDecl *ND) {
std::string RewriteObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD,
int flag) {
std::string S;
if (CopyDestroyCache.count(flag))
if (!CopyDestroyCache.insert(flag).second)
return S;
CopyDestroyCache.insert(flag);
S = "static void __Block_byref_id_object_copy_";
S += utostr(flag);
S += "(void *dst, void *src) {\n";
Expand Down
12 changes: 7 additions & 5 deletions clang/lib/Frontend/SerializedDiagnosticPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ class SDiagsWriter : public DiagnosticConsumer {

/// Emit the string information for diagnostic flags.
unsigned getEmitDiagnosticFlag(DiagnosticsEngine::Level DiagLevel,
unsigned DiagID = 0);
const Diagnostic *Diag = nullptr);

unsigned getEmitDiagnosticFlag(StringRef DiagName);

Expand Down Expand Up @@ -536,11 +536,13 @@ unsigned SDiagsWriter::getEmitCategory(unsigned int category) {
}

unsigned SDiagsWriter::getEmitDiagnosticFlag(DiagnosticsEngine::Level DiagLevel,
unsigned DiagID) {
if (DiagLevel == DiagnosticsEngine::Note)
const Diagnostic *Diag) {
if (!Diag || DiagLevel == DiagnosticsEngine::Note)
return 0; // No flag for notes.

StringRef FlagName = DiagnosticIDs::getWarningOptionForDiag(DiagID);
StringRef FlagName =
Diag->getDiags()->getDiagnosticIDs()->getWarningOptionForDiag(
Diag->getID());
return getEmitDiagnosticFlag(FlagName);
}

Expand Down Expand Up @@ -655,7 +657,7 @@ void SDiagsWriter::EmitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc,
unsigned DiagID = DiagnosticIDs::getCategoryNumberForDiag(Info->getID());
Record.push_back(getEmitCategory(DiagID));
// Emit the diagnostic flag string lazily and get the mapped ID.
Record.push_back(getEmitDiagnosticFlag(Level, Info->getID()));
Record.push_back(getEmitDiagnosticFlag(Level, Info));
} else {
Record.push_back(getEmitCategory());
Record.push_back(getEmitDiagnosticFlag(Level));
Expand Down
10 changes: 7 additions & 3 deletions clang/lib/Frontend/TextDiagnosticPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,17 @@ static void printDiagnosticOptions(raw_ostream &OS,
// flag it as such. Note that diagnostics could also have been mapped by a
// pragma, but we don't currently have a way to distinguish this.
if (Level == DiagnosticsEngine::Error &&
DiagnosticIDs::isBuiltinWarningOrExtension(Info.getID()) &&
!DiagnosticIDs::isDefaultMappingAsError(Info.getID())) {
Info.getDiags()->getDiagnosticIDs()->isWarningOrExtension(
Info.getID()) &&
!Info.getDiags()->getDiagnosticIDs()->isDefaultMappingAsError(
Info.getID())) {
OS << " [-Werror";
Started = true;
}

StringRef Opt = DiagnosticIDs::getWarningOptionForDiag(Info.getID());
StringRef Opt =
Info.getDiags()->getDiagnosticIDs()->getWarningOptionForDiag(
Info.getID());
if (!Opt.empty()) {
OS << (Started ? "," : " [")
<< (Level == DiagnosticsEngine::Remark ? "-R" : "-W") << Opt;
Expand Down
39 changes: 18 additions & 21 deletions clang/lib/Headers/arm_acle.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,28 +264,28 @@ __rbitl(unsigned long __t) {
}

/* 8.3 16-bit multiplications */
#if defined(__ARM_FEATURE_DSP) && __ARM_FEATURE_DSP
static __inline__ int32_t __attribute__((__always_inline__,__nodebug__))
#if defined(__ARM_32BIT_STATE) && __ARM_32BIT_STATE
static __inline__ int32_t __attribute__((__always_inline__,__nodebug__, target("dsp")))
__smulbb(int32_t __a, int32_t __b) {
return __builtin_arm_smulbb(__a, __b);
}
static __inline__ int32_t __attribute__((__always_inline__,__nodebug__))
static __inline__ int32_t __attribute__((__always_inline__,__nodebug__, target("dsp")))
__smulbt(int32_t __a, int32_t __b) {
return __builtin_arm_smulbt(__a, __b);
}
static __inline__ int32_t __attribute__((__always_inline__,__nodebug__))
static __inline__ int32_t __attribute__((__always_inline__,__nodebug__, target("dsp")))
__smultb(int32_t __a, int32_t __b) {
return __builtin_arm_smultb(__a, __b);
}
static __inline__ int32_t __attribute__((__always_inline__,__nodebug__))
static __inline__ int32_t __attribute__((__always_inline__,__nodebug__, target("dsp")))
__smultt(int32_t __a, int32_t __b) {
return __builtin_arm_smultt(__a, __b);
}
static __inline__ int32_t __attribute__((__always_inline__,__nodebug__))
static __inline__ int32_t __attribute__((__always_inline__,__nodebug__, target("dsp")))
__smulwb(int32_t __a, int32_t __b) {
return __builtin_arm_smulwb(__a, __b);
}
static __inline__ int32_t __attribute__((__always_inline__,__nodebug__))
static __inline__ int32_t __attribute__((__always_inline__,__nodebug__, target("dsp")))
__smulwt(int32_t __a, int32_t __b) {
return __builtin_arm_smulwt(__a, __b);
}
Expand All @@ -304,46 +304,46 @@ __smulwt(int32_t __a, int32_t __b) {
#endif

/* 8.4.2 Saturating addition and subtraction intrinsics */
#if defined(__ARM_FEATURE_DSP) && __ARM_FEATURE_DSP
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
#if defined(__ARM_32BIT_STATE) && __ARM_32BIT_STATE
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__, target("dsp")))
__qadd(int32_t __t, int32_t __v) {
return __builtin_arm_qadd(__t, __v);
}

static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__, target("dsp")))
__qsub(int32_t __t, int32_t __v) {
return __builtin_arm_qsub(__t, __v);
}

static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__, target("dsp")))
__qdbl(int32_t __t) {
return __builtin_arm_qadd(__t, __t);
}
#endif

/* 8.4.3 Accumulating multiplications */
#if defined(__ARM_FEATURE_DSP) && __ARM_FEATURE_DSP
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
#if defined(__ARM_32BIT_STATE) && __ARM_32BIT_STATE
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__, target("dsp")))
__smlabb(int32_t __a, int32_t __b, int32_t __c) {
return __builtin_arm_smlabb(__a, __b, __c);
}
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__, target("dsp")))
__smlabt(int32_t __a, int32_t __b, int32_t __c) {
return __builtin_arm_smlabt(__a, __b, __c);
}
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__, target("dsp")))
__smlatb(int32_t __a, int32_t __b, int32_t __c) {
return __builtin_arm_smlatb(__a, __b, __c);
}
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__, target("dsp")))
__smlatt(int32_t __a, int32_t __b, int32_t __c) {
return __builtin_arm_smlatt(__a, __b, __c);
}
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__, target("dsp")))
__smlawb(int32_t __a, int32_t __b, int32_t __c) {
return __builtin_arm_smlawb(__a, __b, __c);
}
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__))
static __inline__ int32_t __attribute__((__always_inline__, __nodebug__, target("dsp")))
__smlawt(int32_t __a, int32_t __b, int32_t __c) {
return __builtin_arm_smlawt(__a, __b, __c);
}
Expand Down Expand Up @@ -621,8 +621,6 @@ __rintnf(float __a) {
#endif

/* 8.8 CRC32 intrinsics */
#if (defined(__ARM_FEATURE_CRC32) && __ARM_FEATURE_CRC32) || \
(defined(__ARM_64BIT_STATE) && __ARM_64BIT_STATE)
static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__, target("crc")))
__crc32b(uint32_t __a, uint8_t __b) {
return __builtin_arm_crc32b(__a, __b);
Expand Down Expand Up @@ -662,7 +660,6 @@ static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__, target
__crc32cd(uint32_t __a, uint64_t __b) {
return __builtin_arm_crc32cd(__a, __b);
}
#endif

/* 8.6 Floating-point data-processing intrinsics */
/* Armv8.3-A Javascript conversion intrinsic */
Expand Down
38 changes: 38 additions & 0 deletions clang/lib/Headers/llvm_libc_wrappers/ctype.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,19 @@
#pragma push_macro("toascii")
#pragma push_macro("tolower")
#pragma push_macro("toupper")
#pragma push_macro("isalnum_l")
#pragma push_macro("isalpha_l")
#pragma push_macro("isascii_l")
#pragma push_macro("isblank_l")
#pragma push_macro("iscntrl_l")
#pragma push_macro("isdigit_l")
#pragma push_macro("isgraph_l")
#pragma push_macro("islower_l")
#pragma push_macro("isprint_l")
#pragma push_macro("ispunct_l")
#pragma push_macro("isspace_l")
#pragma push_macro("isupper_l")
#pragma push_macro("isxdigit_l")

#undef isalnum
#undef isalpha
Expand All @@ -68,6 +81,18 @@
#undef toascii
#undef tolower
#undef toupper
#undef isalnum_l
#undef isalpha_l
#undef iscntrl_l
#undef isdigit_l
#undef islower_l
#undef isgraph_l
#undef isprint_l
#undef ispunct_l
#undef isspace_l
#undef isupper_l
#undef isblank_l
#undef isxdigit_l

#pragma omp begin declare target

Expand All @@ -93,6 +118,19 @@
#pragma pop_macro("toascii")
#pragma pop_macro("tolower")
#pragma pop_macro("toupper")
#pragma pop_macro("isalnum_l")
#pragma pop_macro("isalpha_l")
#pragma pop_macro("isascii_l")
#pragma pop_macro("isblank_l")
#pragma pop_macro("iscntrl_l")
#pragma pop_macro("isdigit_l")
#pragma pop_macro("isgraph_l")
#pragma pop_macro("islower_l")
#pragma pop_macro("isprint_l")
#pragma pop_macro("ispunct_l")
#pragma pop_macro("isspace_l")
#pragma pop_macro("isupper_l")
#pragma pop_macro("isxdigit_l")
#endif

#undef __LIBC_ATTRS
Expand Down
5 changes: 2 additions & 3 deletions clang/lib/Lex/Lexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4325,10 +4325,9 @@ bool Lexer::LexTokenInternal(Token &Result, bool TokAtPhysicalStartOfLine) {
if (Char == '=') {
CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
Kind = tok::caretequal;
} else if (LangOpts.OpenCL && Char == '^') {
CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
Kind = tok::caretcaret;
} else {
if (LangOpts.OpenCL && Char == '^')
Diag(CurPtr, diag::err_opencl_logical_exclusive_or);
Kind = tok::caret;
}
break;
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Parse/ParseDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1109,7 +1109,8 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) {
}
}

T.consumeClose();
if (T.consumeClose())
return nullptr;

DeclEnd = Tok.getLocation();
ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert, TokName);
Expand Down
4 changes: 0 additions & 4 deletions clang/lib/Parse/ParseExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -446,10 +446,6 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
Token OpToken = Tok;
ConsumeToken();

if (OpToken.is(tok::caretcaret)) {
return ExprError(Diag(Tok, diag::err_opencl_logical_exclusive_or));
}

// If we're potentially in a template-id, we may now be able to determine
// whether we're actually in one or not.
if (OpToken.isOneOf(tok::comma, tok::greater, tok::greatergreater,
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Sema/CheckExprLifetime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,8 @@ static bool isInStlNamespace(const Decl *D) {

static bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee) {
if (auto *Conv = dyn_cast_or_null<CXXConversionDecl>(Callee))
if (isRecordWithAttr<PointerAttr>(Conv->getConversionType()))
if (isRecordWithAttr<PointerAttr>(Conv->getConversionType()) &&
Callee->getParent()->hasAttr<OwnerAttr>())
return true;
if (!isInStlNamespace(Callee->getParent()))
return false;
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/Sema/Sema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1683,7 +1683,7 @@ void Sema::EmitCurrentDiagnostic(unsigned DiagID) {
// that is different from the last template instantiation where
// we emitted an error, print a template instantiation
// backtrace.
if (!DiagnosticIDs::isBuiltinNote(DiagID))
if (!Diags.getDiagnosticIDs()->isNote(DiagID))
PrintContextStack();
}

Expand All @@ -1697,7 +1697,8 @@ bool Sema::hasUncompilableErrorOccurred() const {
if (Loc == DeviceDeferredDiags.end())
return false;
for (auto PDAt : Loc->second) {
if (DiagnosticIDs::isDefaultMappingAsError(PDAt.second.getDiagID()))
if (Diags.getDiagnosticIDs()->isDefaultMappingAsError(
PDAt.second.getDiagID()))
return true;
}
return false;
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Sema/SemaCUDA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -835,7 +835,7 @@ SemaBase::SemaDiagnosticBuilder SemaCUDA::DiagIfDeviceCode(SourceLocation Loc,
if (!getLangOpts().CUDAIsDevice)
return SemaDiagnosticBuilder::K_Nop;
if (SemaRef.IsLastErrorImmediate &&
getDiagnostics().getDiagnosticIDs()->isBuiltinNote(DiagID))
getDiagnostics().getDiagnosticIDs()->isNote(DiagID))
return SemaDiagnosticBuilder::K_Immediate;
return (SemaRef.getEmissionStatus(CurFunContext) ==
Sema::FunctionEmissionStatus::Emitted)
Expand Down Expand Up @@ -866,7 +866,7 @@ Sema::SemaDiagnosticBuilder SemaCUDA::DiagIfHostCode(SourceLocation Loc,
if (getLangOpts().CUDAIsDevice)
return SemaDiagnosticBuilder::K_Nop;
if (SemaRef.IsLastErrorImmediate &&
getDiagnostics().getDiagnosticIDs()->isBuiltinNote(DiagID))
getDiagnostics().getDiagnosticIDs()->isNote(DiagID))
return SemaDiagnosticBuilder::K_Immediate;
return (SemaRef.getEmissionStatus(CurFunContext) ==
Sema::FunctionEmissionStatus::Emitted)
Expand Down
1 change: 0 additions & 1 deletion clang/lib/Sema/SemaCodeComplete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,6 @@ static QualType getPreferredTypeOfBinaryRHS(Sema &S, Expr *LHS,
// Logical operators, assume we want bool.
case tok::ampamp:
case tok::pipepipe:
case tok::caretcaret:
return S.getASTContext().BoolTy;
// Operators often used for bit manipulation are typically used with the type
// of the left argument.
Expand Down
26 changes: 21 additions & 5 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -852,22 +852,38 @@ static void handleDiagnoseIfAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
if (!checkFunctionConditionAttr(S, D, AL, Cond, Msg))
return;

StringRef DiagTypeStr;
if (!S.checkStringLiteralArgumentAttr(AL, 2, DiagTypeStr))
StringRef DefaultSevStr;
if (!S.checkStringLiteralArgumentAttr(AL, 2, DefaultSevStr))
return;

DiagnoseIfAttr::DiagnosticType DiagType;
if (!DiagnoseIfAttr::ConvertStrToDiagnosticType(DiagTypeStr, DiagType)) {
DiagnoseIfAttr::DefaultSeverity DefaultSev;
if (!DiagnoseIfAttr::ConvertStrToDefaultSeverity(DefaultSevStr, DefaultSev)) {
S.Diag(AL.getArgAsExpr(2)->getBeginLoc(),
diag::err_diagnose_if_invalid_diagnostic_type);
return;
}

StringRef WarningGroup;
SmallVector<StringRef, 2> Options;
if (AL.getNumArgs() > 3) {
if (!S.checkStringLiteralArgumentAttr(AL, 3, WarningGroup))
return;
if (WarningGroup.empty() ||
!S.getDiagnostics().getDiagnosticIDs()->getGroupForWarningOption(
WarningGroup)) {
S.Diag(AL.getArgAsExpr(3)->getBeginLoc(),
diag::err_diagnose_if_unknown_warning)
<< WarningGroup;
return;
}
}

bool ArgDependent = false;
if (const auto *FD = dyn_cast<FunctionDecl>(D))
ArgDependent = ArgumentDependenceChecker(FD).referencesArgs(Cond);
D->addAttr(::new (S.Context) DiagnoseIfAttr(
S.Context, AL, Cond, Msg, DiagType, ArgDependent, cast<NamedDecl>(D)));
S.Context, AL, Cond, Msg, DefaultSev, WarningGroup, ArgDependent,
cast<NamedDecl>(D)));
}

static void handleNoBuiltinAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/Sema/SemaModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,14 @@ DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc,
else
VisibleModules.setVisible(Mod, ImportLoc);

assert((!Mod->isModulePartitionImplementation() || getCurrentModule()) &&
"We can only import a partition unit in a named module.");
if (Mod->isModulePartitionImplementation() &&
getCurrentModule()->isModuleInterfaceUnit())
Diag(ImportLoc,
diag::warn_import_implementation_partition_unit_in_interface_unit)
<< Mod->Name;

checkModuleImportContext(*this, Mod, ImportLoc, CurContext);

// FIXME: we should support importing a submodule within a different submodule
Expand Down
58 changes: 37 additions & 21 deletions clang/lib/Sema/SemaOverload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6567,29 +6567,22 @@ static void
collectViableConversionCandidates(Sema &SemaRef, Expr *From, QualType ToType,
UnresolvedSetImpl &ViableConversions,
OverloadCandidateSet &CandidateSet) {
for (unsigned I = 0, N = ViableConversions.size(); I != N; ++I) {
DeclAccessPair FoundDecl = ViableConversions[I];
for (const DeclAccessPair &FoundDecl : ViableConversions.pairs()) {
NamedDecl *D = FoundDecl.getDecl();
CXXRecordDecl *ActingContext = cast<CXXRecordDecl>(D->getDeclContext());
if (isa<UsingShadowDecl>(D))
D = cast<UsingShadowDecl>(D)->getTargetDecl();

CXXConversionDecl *Conv;
FunctionTemplateDecl *ConvTemplate;
if ((ConvTemplate = dyn_cast<FunctionTemplateDecl>(D)))
Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
else
Conv = cast<CXXConversionDecl>(D);

if (ConvTemplate)
if (auto *ConvTemplate = dyn_cast<FunctionTemplateDecl>(D)) {
SemaRef.AddTemplateConversionCandidate(
ConvTemplate, FoundDecl, ActingContext, From, ToType, CandidateSet,
/*AllowObjCConversionOnExplicit=*/false, /*AllowExplicit*/ true);
else
SemaRef.AddConversionCandidate(Conv, FoundDecl, ActingContext, From,
ToType, CandidateSet,
/*AllowObjCConversionOnExplicit=*/false,
/*AllowExplicit*/ true);
/*AllowObjCConversionOnExplicit=*/false, /*AllowExplicit=*/true);
continue;
}
CXXConversionDecl *Conv = cast<CXXConversionDecl>(D);
SemaRef.AddConversionCandidate(
Conv, FoundDecl, ActingContext, From, ToType, CandidateSet,
/*AllowObjCConversionOnExplicit=*/false, /*AllowExplicit=*/true);
}
}

Expand Down Expand Up @@ -7307,8 +7300,10 @@ static bool diagnoseDiagnoseIfAttrsWith(Sema &S, const NamedDecl *ND,
return false;

auto WarningBegin = std::stable_partition(
Attrs.begin(), Attrs.end(),
[](const DiagnoseIfAttr *DIA) { return DIA->isError(); });
Attrs.begin(), Attrs.end(), [](const DiagnoseIfAttr *DIA) {
return DIA->getDefaultSeverity() == DiagnoseIfAttr::DS_error &&
DIA->getWarningGroup().empty();
});

// Note that diagnose_if attributes are late-parsed, so they appear in the
// correct order (unlike enable_if attributes).
Expand All @@ -7322,11 +7317,32 @@ static bool diagnoseDiagnoseIfAttrsWith(Sema &S, const NamedDecl *ND,
return true;
}

auto ToSeverity = [](DiagnoseIfAttr::DefaultSeverity Sev) {
switch (Sev) {
case DiagnoseIfAttr::DS_warning:
return diag::Severity::Warning;
case DiagnoseIfAttr::DS_error:
return diag::Severity::Error;
}
llvm_unreachable("Fully covered switch above!");
};

for (const auto *DIA : llvm::make_range(WarningBegin, Attrs.end()))
if (IsSuccessful(DIA)) {
S.Diag(Loc, diag::warn_diagnose_if_succeeded) << DIA->getMessage();
S.Diag(DIA->getLocation(), diag::note_from_diagnose_if)
<< DIA->getParent() << DIA->getCond()->getSourceRange();
if (DIA->getWarningGroup().empty() &&
DIA->getDefaultSeverity() == DiagnoseIfAttr::DS_warning) {
S.Diag(Loc, diag::warn_diagnose_if_succeeded) << DIA->getMessage();
S.Diag(DIA->getLocation(), diag::note_from_diagnose_if)
<< DIA->getParent() << DIA->getCond()->getSourceRange();
} else {
auto DiagGroup = S.Diags.getDiagnosticIDs()->getGroupForWarningOption(
DIA->getWarningGroup());
assert(DiagGroup);
auto DiagID = S.Diags.getDiagnosticIDs()->getCustomDiagID(
{ToSeverity(DIA->getDefaultSeverity()), "%0",
DiagnosticIDs::CLASS_WARNING, false, false, *DiagGroup});
S.Diag(Loc, DiagID) << DIA->getMessage();
}
}

return false;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Sema/SemaTemplateDeduction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3411,7 +3411,7 @@ DeduceTemplateArguments(Sema &S, T *Partial,
if (TemplateDeductionResult Result = ::DeduceTemplateArguments(
S, Partial->getTemplateParameters(),
Partial->getTemplateArgs().asArray(), TemplateArgs, Info, Deduced,
/*NumberOfArgumentsMustMatch=*/false, /*PartialOrdering=*/true,
/*NumberOfArgumentsMustMatch=*/false, /*PartialOrdering=*/false,
PackFold::ParameterToArgument,
/*HasDeducedAnyParam=*/nullptr);
Result != TemplateDeductionResult::Success)
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,8 @@ static void instantiateDependentDiagnoseIfAttr(
if (Cond)
New->addAttr(new (S.getASTContext()) DiagnoseIfAttr(
S.getASTContext(), *DIA, Cond, DIA->getMessage(),
DIA->getDiagnosticType(), DIA->getArgDependent(), New));
DIA->getDefaultSeverity(), DIA->getWarningGroup(),
DIA->getArgDependent(), New));
}

// Constructs and adds to New a new instance of CUDALaunchBoundsAttr using
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Serialization/ASTReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6641,7 +6641,7 @@ void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) {
// command line (-w, -Weverything, -Werror, ...) along with any explicit
// -Wblah flags.
unsigned Flags = Record[Idx++];
DiagState Initial;
DiagState Initial(*Diag.getDiagnosticIDs());
Initial.SuppressSystemWarnings = Flags & 1; Flags >>= 1;
Initial.ErrorsAsFatal = Flags & 1; Flags >>= 1;
Initial.WarningsAsErrors = Flags & 1; Flags >>= 1;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Serialization/ASTWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3219,7 +3219,7 @@ void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,
// Skip default mappings. We have a mapping for every diagnostic ever
// emitted, regardless of whether it was customized.
if (!I.second.isPragma() &&
I.second == DiagnosticIDs::getDefaultMapping(I.first))
I.second == Diag.getDiagnosticIDs()->getDefaultMapping(I.first))
continue;
Mappings.push_back(I);
}
Expand Down
470 changes: 299 additions & 171 deletions clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions clang/lib/StaticAnalyzer/Checkers/MoveChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
//
//===----------------------------------------------------------------------===//

#include "Move.h"
#include "clang/AST/Attr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/Driver/DriverDiagnostic.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -635,8 +635,9 @@ class VarBindingsCollector : public StoreManager::BindingsHandler {
};
} // namespace

Bindings getAllVarBindingsForSymbol(ProgramStateManager &Manager,
const ExplodedNode *Node, SymbolRef Sym) {
static Bindings getAllVarBindingsForSymbol(ProgramStateManager &Manager,
const ExplodedNode *Node,
SymbolRef Sym) {
Bindings Result;
VarBindingsCollector Collector{Sym, Result};
while (Result.empty() && Node) {
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ bool SmartPtrModeling::isBoolConversionMethod(const CallEvent &Call) const {

constexpr llvm::StringLiteral BASIC_OSTREAM_NAMES[] = {"basic_ostream"};

bool isStdBasicOstream(const Expr *E) {
static bool isStdBasicOstream(const Expr *E) {
const auto *RD = E->getType()->getAsCXXRecordDecl();
return hasStdClassWithName(RD, BASIC_OSTREAM_NAMES);
}
Expand All @@ -250,7 +250,7 @@ static bool isStdFunctionCall(const CallEvent &Call) {
return Call.getDecl() && Call.getDecl()->getDeclContext()->isStdNamespace();
}

bool isStdOstreamOperatorCall(const CallEvent &Call) {
static bool isStdOstreamOperatorCall(const CallEvent &Call) {
if (Call.getNumArgs() != 2 || !isStdFunctionCall(Call))
return false;
const auto *FC = dyn_cast<SimpleFunctionCall>(&Call);
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ static const MemSpaceRegion *getStackOrGlobalSpaceRegion(const MemRegion *R) {
return nullptr;
}

const MemRegion *getOriginBaseRegion(const MemRegion *Reg) {
static const MemRegion *getOriginBaseRegion(const MemRegion *Reg) {
Reg = Reg->getBaseRegion();
while (const auto *SymReg = dyn_cast<SymbolicRegion>(Reg)) {
const auto *OriginReg = SymReg->getSymbol()->getOriginRegion();
Expand All @@ -316,7 +316,7 @@ const MemRegion *getOriginBaseRegion(const MemRegion *Reg) {
return Reg;
}

std::optional<std::string> printReferrer(const MemRegion *Referrer) {
static std::optional<std::string> printReferrer(const MemRegion *Referrer) {
assert(Referrer);
const StringRef ReferrerMemorySpace = [](const MemSpaceRegion *Space) {
if (isa<StaticGlobalSpaceRegion>(Space))
Expand Down Expand Up @@ -354,7 +354,7 @@ std::optional<std::string> printReferrer(const MemRegion *Referrer) {

/// Check whether \p Region refers to a freshly minted symbol after an opaque
/// function call.
bool isInvalidatedSymbolRegion(const MemRegion *Region) {
static bool isInvalidatedSymbolRegion(const MemRegion *Region) {
const auto *SymReg = Region->getAs<SymbolicRegion>();
if (!SymReg)
return false;
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/StaticAnalyzer/Checkers/StdVariantChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ REGISTER_MAP_WITH_PROGRAMSTATE(VariantHeldTypeMap, const MemRegion *, QualType)

namespace clang::ento::tagged_union_modeling {

const CXXConstructorDecl *
static const CXXConstructorDecl *
getConstructorDeclarationForCall(const CallEvent &Call) {
const auto *ConstructorCall = dyn_cast<CXXConstructorCall>(&Call);
if (!ConstructorCall)
Expand Down Expand Up @@ -76,7 +76,7 @@ bool isMoveAssignmentCall(const CallEvent &Call) {
return AsMethodDecl->isMoveAssignmentOperator();
}

bool isStdType(const Type *Type, llvm::StringRef TypeName) {
static bool isStdType(const Type *Type, llvm::StringRef TypeName) {
auto *Decl = Type->getAsRecordDecl();
if (!Decl)
return false;
Expand Down
3 changes: 1 addition & 2 deletions clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,6 @@ void VLASizeChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
return;

ASTContext &Ctx = C.getASTContext();
SValBuilder &SVB = C.getSValBuilder();
ProgramStateRef State = C.getState();
QualType TypeToCheck;

Expand Down Expand Up @@ -301,7 +300,7 @@ void VLASizeChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {
if (VD) {
State =
setDynamicExtent(State, State->getRegion(VD, C.getLocationContext()),
ArraySize.castAs<NonLoc>(), SVB);
ArraySize.castAs<NonLoc>());
}

// Remember our assumptions!
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ const PointerToMemberData *BasicValueFactory::getPointerToMemberData(
return D;
}

LLVM_ATTRIBUTE_UNUSED bool hasNoRepeatedElements(
LLVM_ATTRIBUTE_UNUSED static bool hasNoRepeatedElements(
llvm::ImmutableList<const CXXBaseSpecifier *> BaseSpecList) {
llvm::SmallPtrSet<QualType, 16> BaseSpecSeen;
for (const CXXBaseSpecifier *BaseSpec : BaseSpecList) {
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/StaticAnalyzer/Core/DynamicExtent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ DefinedOrUnknownSVal getDynamicElementCountWithOffset(ProgramStateRef State,
}

ProgramStateRef setDynamicExtent(ProgramStateRef State, const MemRegion *MR,
DefinedOrUnknownSVal Size, SValBuilder &SVB) {
DefinedOrUnknownSVal Size) {
MR = MR->StripCasts();

if (Size.isUnknown())
Expand Down
3 changes: 1 addition & 2 deletions clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -817,8 +817,7 @@ ProgramStateRef ExprEngine::bindReturnValue(const CallEvent &Call,
if (Size.isUndef())
Size = UnknownVal();

State = setDynamicExtent(State, MR, Size.castAs<DefinedOrUnknownSVal>(),
svalBuilder);
State = setDynamicExtent(State, MR, Size.castAs<DefinedOrUnknownSVal>());
} else {
R = svalBuilder.conjureSymbolVal(nullptr, E, LCtx, ResultTy, Count);
}
Expand Down
7 changes: 4 additions & 3 deletions clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1211,18 +1211,19 @@ const arrowIndices = )<<<";
OS.str());
}

std::string getSpanBeginForControl(const char *ClassName, unsigned Index) {
static std::string getSpanBeginForControl(const char *ClassName,
unsigned Index) {
std::string Result;
llvm::raw_string_ostream OS(Result);
OS << "<span id=\"" << ClassName << Index << "\">";
return Result;
}

std::string getSpanBeginForControlStart(unsigned Index) {
static std::string getSpanBeginForControlStart(unsigned Index) {
return getSpanBeginForControl("start", Index);
}

std::string getSpanBeginForControlEnd(unsigned Index) {
static std::string getSpanBeginForControlEnd(unsigned Index) {
return getSpanBeginForControl("end", Index);
}

Expand Down
6 changes: 3 additions & 3 deletions clang/lib/StaticAnalyzer/Core/LoopUnrolling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,8 @@ static bool isPossiblyEscaped(ExplodedNode *N, const DeclRefExpr *DR) {
llvm_unreachable("Reached root without finding the declaration of VD");
}

bool shouldCompletelyUnroll(const Stmt *LoopStmt, ASTContext &ASTCtx,
ExplodedNode *Pred, unsigned &maxStep) {
static bool shouldCompletelyUnroll(const Stmt *LoopStmt, ASTContext &ASTCtx,
ExplodedNode *Pred, unsigned &maxStep) {

if (!isLoopStmt(LoopStmt))
return false;
Expand Down Expand Up @@ -297,7 +297,7 @@ bool shouldCompletelyUnroll(const Stmt *LoopStmt, ASTContext &ASTCtx,
return !isPossiblyEscaped(Pred, CounterVarRef);
}

bool madeNewBranch(ExplodedNode *N, const Stmt *LoopStmt) {
static bool madeNewBranch(ExplodedNode *N, const Stmt *LoopStmt) {
const Stmt *S = nullptr;
while (!N->pred_empty()) {
if (N->succ_size() > 1)
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ RangeSet RangeSet::Factory::unite(RangeSet Original, llvm::APSInt From,
}

template <typename T>
void swapIterators(T &First, T &FirstEnd, T &Second, T &SecondEnd) {
static void swapIterators(T &First, T &FirstEnd, T &Second, T &SecondEnd) {
std::swap(First, Second);
std::swap(FirstEnd, SecondEnd);
}
Expand Down Expand Up @@ -2624,7 +2624,7 @@ EquivalenceClass::removeMember(ProgramStateRef State, const SymbolRef Old) {
}

// Re-evaluate an SVal with top-level `State->assume` logic.
[[nodiscard]] ProgramStateRef
[[nodiscard]] static ProgramStateRef
reAssume(ProgramStateRef State, const RangeSet *Constraint, SVal TheValue) {
if (!Constraint)
return State;
Expand Down
22 changes: 12 additions & 10 deletions clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,22 +210,24 @@ DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const Stmt *stmt,
return nonloc::SymbolVal(sym);
}

DefinedOrUnknownSVal
SValBuilder::getConjuredHeapSymbolVal(const Expr *E,
const LocationContext *LCtx,
unsigned VisitCount) {
DefinedSVal SValBuilder::getConjuredHeapSymbolVal(const Expr *E,
const LocationContext *LCtx,
unsigned VisitCount) {
QualType T = E->getType();
return getConjuredHeapSymbolVal(E, LCtx, T, VisitCount);
}

DefinedOrUnknownSVal
SValBuilder::getConjuredHeapSymbolVal(const Expr *E,
const LocationContext *LCtx,
QualType type, unsigned VisitCount) {
DefinedSVal SValBuilder::getConjuredHeapSymbolVal(const Expr *E,
const LocationContext *LCtx,
QualType type,
unsigned VisitCount) {
assert(Loc::isLocType(type));
assert(SymbolManager::canSymbolicate(type));
if (type->isNullPtrType())
return makeZeroVal(type);
if (type->isNullPtrType()) {
// makeZeroVal() returns UnknownVal only in case of FP number, which
// is not the case.
return makeZeroVal(type).castAs<DefinedSVal>();
}

SymbolRef sym = SymMgr.conjureSymbol(E, LCtx, type, VisitCount);
return loc::MemRegionVal(MemMgr.getSymbolicHeapRegion(sym));
Expand Down
1 change: 0 additions & 1 deletion clang/lib/StaticAnalyzer/Core/TextDiagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ class TextDiagnostics : public PathDiagnosticConsumer {
? " [" + PD->getCheckerName() + "]"
: "")
.str();

reportPiece(WarnID, PD->getLocation().asLocation(),
(PD->getShortDescription() + WarningMsg).str(),
PD->path.back()->getRanges(), PD->path.back()->getFixits());
Expand Down
3 changes: 3 additions & 0 deletions clang/test/AST/ByteCode/invalid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,7 @@ namespace Casts {
B b;
(void)*reinterpret_cast<void*>(&b); // both-error {{indirection not permitted on operand of type 'void *'}}
}

/// Just make sure this doesn't crash.
float PR9558 = reinterpret_cast<const float&>("asd");
}
46 changes: 46 additions & 0 deletions clang/test/Analysis/NewDelete-atomics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,32 @@ class DifferentlyNamed {
T *getPtr() const { return Ptr; } // no-warning
};

// Also IntrusivePtr with different name and outline release in destructor
template <typename T>
class DifferentlyNamedOutlineRelease {
T *Ptr;

public:
DifferentlyNamedOutlineRelease(T *Ptr) : Ptr(Ptr) {
Ptr->incRef();
}

DifferentlyNamedOutlineRelease(const DifferentlyNamedOutlineRelease &Other) : Ptr(Other.Ptr) {
Ptr->incRef();
}

void releasePtr(void) {
delete Ptr;
}

~DifferentlyNamedOutlineRelease() {
if (Ptr->decRef() == 1)
releasePtr();
}

T *getPtr() const { return Ptr; } // no-warning
};

void testDestroyLocalRefPtr() {
IntrusivePtr<RawObj> p1(new RawObj());
{
Expand Down Expand Up @@ -176,3 +202,23 @@ void testDestroyLocalRefPtrWithAtomicsDifferentlyNamed(
// p1 still maintains ownership. The object is not deleted.
p1.getPtr()->foo(); // no-warning
}

void testDestroyLocalRefPtrWithOutlineRelease() {
DifferentlyNamedOutlineRelease <RawObj> p1(new RawObj());
{
DifferentlyNamedOutlineRelease <RawObj> p2(p1);
}

// p1 still maintains ownership. The object is not deleted.
p1.getPtr()->foo(); // no-warning
}

void testDestroySymbolicRefPtrWithOutlineRelease(
const DifferentlyNamedOutlineRelease<RawObj> &p1) {
{
DifferentlyNamedOutlineRelease <RawObj> p2(p1);
}

// p1 still maintains ownership. The object is not deleted.
p1.getPtr()->foo(); // no-warning
}
17 changes: 0 additions & 17 deletions clang/test/Analysis/NewDelete-checker-test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@ extern "C" void *malloc(size_t);
extern "C" void free (void* ptr);
int *global;

//------------------
// check for leaks
//------------------

//----- Standard non-placement operators
void testGlobalOpNew() {
void *p = operator new(0);
Expand All @@ -67,19 +63,6 @@ void testGlobalNoThrowPlacementExprNewBeforeOverload() {
int *p = new(std::nothrow) int;
} // leak-warning{{Potential leak of memory pointed to by 'p'}}

//----- Standard pointer placement operators
void testGlobalPointerPlacementNew() {
int i;

void *p1 = operator new(0, &i); // no warn

void *p2 = operator new[](0, &i); // no warn

int *p3 = new(&i) int; // no warn

int *p4 = new(&i) int[0]; // no warn
}

//----- Other cases
void testNewMemoryIsInHeap() {
int *p = new int;
Expand Down
4 changes: 2 additions & 2 deletions clang/test/Analysis/NewDelete-intersections.mm
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
// RUN: -analyzer-checker=core \
// RUN: -analyzer-checker=cplusplus.NewDelete

// leak-no-diagnostics

// RUN: %clang_analyze_cc1 -std=c++11 -DLEAKS -fblocks %s \
// RUN: -verify=leak \
// RUN: -analyzer-checker=core \
// RUN: -analyzer-checker=cplusplus.NewDeleteLeaks

// leak-no-diagnostics

// RUN: %clang_analyze_cc1 -std=c++11 -DLEAKS -fblocks %s \
// RUN: -verify=mismatch \
// RUN: -analyzer-checker=core \
Expand Down
35 changes: 0 additions & 35 deletions clang/test/Analysis/malloc-interprocedural.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,38 +98,3 @@ int uafAndCallsFooWithEmptyReturn(void) {
fooWithEmptyReturn(12);
return *x; // expected-warning {{Use of memory after it is freed}}
}


// If we inline any of the malloc-family functions, the checker shouldn't also
// try to do additional modeling.
char *strndup(const char *str, size_t n) {
if (!str)
return 0;

// DO NOT FIX. This is to test that we are actually using the inlined
// behavior!
if (n < 5)
return 0;

size_t length = strlen(str);
if (length < n)
n = length;

char *result = malloc(n + 1);
memcpy(result, str, n);
result[n] = '\0';
return result;
}

void useStrndup(size_t n) {
if (n == 0) {
(void)strndup(0, 20); // no-warning
return;
} else if (n < 5) {
(void)strndup("hi there", n); // no-warning
return;
} else {
(void)strndup("hi there", n);
return; // expected-warning{{leak}}
}
}
80 changes: 80 additions & 0 deletions clang/test/Analysis/malloc-refcounted.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -verify %s
//

typedef __SIZE_TYPE__ size_t;

typedef enum memory_order {
memory_order_relaxed = __ATOMIC_RELAXED,
} memory_order;

void *calloc(size_t, size_t);
void free(void *);

struct SomeData {
int i;
_Atomic int ref;
};

static struct SomeData *alloc_data(void)
{
struct SomeData *data = calloc(sizeof(*data), 1);

__c11_atomic_store(&data->ref, 2, memory_order_relaxed);
return data;
}

static void put_data(struct SomeData *data)
{
if (__c11_atomic_fetch_sub(&data->ref, 1, memory_order_relaxed) == 1)
free(data);
}

static int dec_refcounter(struct SomeData *data)
{
return __c11_atomic_fetch_sub(&data->ref, 1, memory_order_relaxed) == 1;
}

static void put_data_nested(struct SomeData *data)
{
if (dec_refcounter(data))
free(data);
}

static void put_data_uncond(struct SomeData *data)
{
free(data);
}

static void put_data_unrelated_atomic(struct SomeData *data)
{
free(data);
__c11_atomic_fetch_sub(&data->ref, 1, memory_order_relaxed);
}

void test_no_uaf(void)
{
struct SomeData *data = alloc_data();
put_data(data);
data->i += 1; // no warning
}

void test_no_uaf_nested(void)
{
struct SomeData *data = alloc_data();
put_data_nested(data);
data->i += 1; // no warning
}

void test_uaf(void)
{
struct SomeData *data = alloc_data();
put_data_uncond(data);
data->i += 1; // expected-warning{{Use of memory after it is freed}}
}

void test_no_uaf_atomic_after(void)
{
struct SomeData *data = alloc_data();
put_data_unrelated_atomic(data);
data->i += 1; // expected-warning{{Use of memory after it is freed}}
}
3 changes: 1 addition & 2 deletions clang/test/CXX/module/module.import/p2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,8 @@ void test() {
}

//--- UseInPartA.cppm
// expected-no-diagnostics
export module M:partA;
import :impl;
import :impl; // expected-warning {{importing an implementation partition unit in a module interface is not recommended.}}
void test() {
A a;
}
Expand Down
76 changes: 73 additions & 3 deletions clang/test/CodeGen/arm_acle.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
// RUN: %clang_cc1 -ffreestanding -triple armv8a-none-eabi -O0 -disable-O0-optnone -emit-llvm -o - %s | opt -S -passes=mem2reg | FileCheck %s -check-prefixes=ARM,AArch32
// RUN: %clang_cc1 -ffreestanding -triple armv8a-none-eabi -target-feature +crc -target-feature +dsp -O0 -disable-O0-optnone -emit-llvm -o - %s | opt -S -passes=mem2reg | FileCheck %s -check-prefixes=ARM,AArch32
// RUN: %clang_cc1 -ffreestanding -Wno-error=implicit-function-declaration -triple aarch64-none-elf -target-feature +neon -target-feature +crc -target-feature +crypto -O0 -disable-O0-optnone -emit-llvm -o - %s | opt -S -passes=mem2reg | FileCheck %s -check-prefixes=ARM,AArch64
// RUN: %clang_cc1 -ffreestanding -triple aarch64-none-elf -target-feature +v8.3a -target-feature +crc -O0 -disable-O0-optnone -emit-llvm -o - %s | opt -S -passes=mem2reg | FileCheck %s -check-prefixes=ARM,AArch64,AArch6483
Expand Down Expand Up @@ -638,12 +639,15 @@ uint32_t test_usat(int32_t t) {
#endif

/* 9.4.2 Saturating addition and subtraction intrinsics */
#ifdef __ARM_FEATURE_DSP
#ifdef __ARM_32BIT_STATE
// AArch32-LABEL: @test_qadd(
// AArch32-NEXT: entry:
// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qadd(i32 [[A:%.*]], i32 [[B:%.*]])
// AArch32-NEXT: ret i32 [[TMP0]]
//
#ifndef __ARM_FEATURE_DSP
__attribute__((target("dsp")))
#endif
int32_t test_qadd(int32_t a, int32_t b) {
return __qadd(a, b);
}
Expand All @@ -653,6 +657,9 @@ int32_t test_qadd(int32_t a, int32_t b) {
// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qsub(i32 [[A:%.*]], i32 [[B:%.*]])
// AArch32-NEXT: ret i32 [[TMP0]]
//
#ifndef __ARM_FEATURE_DSP
__attribute__((target("dsp")))
#endif
int32_t test_qsub(int32_t a, int32_t b) {
return __qsub(a, b);
}
Expand All @@ -664,6 +671,9 @@ extern int32_t f();
// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qadd(i32 [[CALL]], i32 [[CALL]])
// AArch32-NEXT: ret i32 [[TMP0]]
//
#ifndef __ARM_FEATURE_DSP
__attribute__((target("dsp")))
#endif
int32_t test_qdbl() {
return __qdbl(f());
}
Expand All @@ -672,12 +682,15 @@ int32_t test_qdbl() {
/*
* 9.3 16-bit multiplications
*/
#if __ARM_FEATURE_DSP
#ifdef __ARM_32BIT_STATE
// AArch32-LABEL: @test_smulbb(
// AArch32-NEXT: entry:
// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smulbb(i32 [[A:%.*]], i32 [[B:%.*]])
// AArch32-NEXT: ret i32 [[TMP0]]
//
#ifndef __ARM_FEATURE_DSP
__attribute__((target("dsp")))
#endif
int32_t test_smulbb(int32_t a, int32_t b) {
return __smulbb(a, b);
}
Expand All @@ -687,6 +700,9 @@ int32_t test_smulbb(int32_t a, int32_t b) {
// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smulbt(i32 [[A:%.*]], i32 [[B:%.*]])
// AArch32-NEXT: ret i32 [[TMP0]]
//
#ifndef __ARM_FEATURE_DSP
__attribute__((target("dsp")))
#endif
int32_t test_smulbt(int32_t a, int32_t b) {
return __smulbt(a, b);
}
Expand All @@ -696,6 +712,9 @@ int32_t test_smulbt(int32_t a, int32_t b) {
// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smultb(i32 [[A:%.*]], i32 [[B:%.*]])
// AArch32-NEXT: ret i32 [[TMP0]]
//
#ifndef __ARM_FEATURE_DSP
__attribute__((target("dsp")))
#endif
int32_t test_smultb(int32_t a, int32_t b) {
return __smultb(a, b);
}
Expand All @@ -705,6 +724,9 @@ int32_t test_smultb(int32_t a, int32_t b) {
// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smultt(i32 [[A:%.*]], i32 [[B:%.*]])
// AArch32-NEXT: ret i32 [[TMP0]]
//
#ifndef __ARM_FEATURE_DSP
__attribute__((target("dsp")))
#endif
int32_t test_smultt(int32_t a, int32_t b) {
return __smultt(a, b);
}
Expand All @@ -714,6 +736,9 @@ int32_t test_smultt(int32_t a, int32_t b) {
// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smulwb(i32 [[A:%.*]], i32 [[B:%.*]])
// AArch32-NEXT: ret i32 [[TMP0]]
//
#ifndef __ARM_FEATURE_DSP
__attribute__((target("dsp")))
#endif
int32_t test_smulwb(int32_t a, int32_t b) {
return __smulwb(a, b);
}
Expand All @@ -723,18 +748,24 @@ int32_t test_smulwb(int32_t a, int32_t b) {
// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smulwt(i32 [[A:%.*]], i32 [[B:%.*]])
// AArch32-NEXT: ret i32 [[TMP0]]
//
#ifndef __ARM_FEATURE_DSP
__attribute__((target("dsp")))
#endif
int32_t test_smulwt(int32_t a, int32_t b) {
return __smulwt(a, b);
}
#endif

/* 9.4.3 Accumultating multiplications */
#if __ARM_FEATURE_DSP
#ifdef __ARM_32BIT_STATE
// AArch32-LABEL: @test_smlabb(
// AArch32-NEXT: entry:
// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlabb(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
// AArch32-NEXT: ret i32 [[TMP0]]
//
#ifndef __ARM_FEATURE_DSP
__attribute__((target("dsp")))
#endif
int32_t test_smlabb(int32_t a, int32_t b, int32_t c) {
return __smlabb(a, b, c);
}
Expand All @@ -744,6 +775,9 @@ int32_t test_smlabb(int32_t a, int32_t b, int32_t c) {
// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlabt(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
// AArch32-NEXT: ret i32 [[TMP0]]
//
#ifndef __ARM_FEATURE_DSP
__attribute__((target("dsp")))
#endif
int32_t test_smlabt(int32_t a, int32_t b, int32_t c) {
return __smlabt(a, b, c);
}
Expand All @@ -753,6 +787,9 @@ int32_t test_smlabt(int32_t a, int32_t b, int32_t c) {
// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlatb(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
// AArch32-NEXT: ret i32 [[TMP0]]
//
#ifndef __ARM_FEATURE_DSP
__attribute__((target("dsp")))
#endif
int32_t test_smlatb(int32_t a, int32_t b, int32_t c) {
return __smlatb(a, b, c);
}
Expand All @@ -762,6 +799,9 @@ int32_t test_smlatb(int32_t a, int32_t b, int32_t c) {
// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlatt(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
// AArch32-NEXT: ret i32 [[TMP0]]
//
#ifndef __ARM_FEATURE_DSP
__attribute__((target("dsp")))
#endif
int32_t test_smlatt(int32_t a, int32_t b, int32_t c) {
return __smlatt(a, b, c);
}
Expand All @@ -771,6 +811,9 @@ int32_t test_smlatt(int32_t a, int32_t b, int32_t c) {
// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlawb(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
// AArch32-NEXT: ret i32 [[TMP0]]
//
#ifndef __ARM_FEATURE_DSP
__attribute__((target("dsp")))
#endif
int32_t test_smlawb(int32_t a, int32_t b, int32_t c) {
return __smlawb(a, b, c);
}
Expand All @@ -780,6 +823,9 @@ int32_t test_smlawb(int32_t a, int32_t b, int32_t c) {
// AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlawt(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
// AArch32-NEXT: ret i32 [[TMP0]]
//
#ifndef __ARM_FEATURE_DSP
__attribute__((target("dsp")))
#endif
int32_t test_smlawt(int32_t a, int32_t b, int32_t c) {
return __smlawt(a, b, c);
}
Expand Down Expand Up @@ -1335,6 +1381,9 @@ int32_t test_smusdx(int16x2_t a, int16x2_t b) {
// AArch64-NEXT: [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32b(i32 [[A:%.*]], i32 [[TMP0]])
// AArch64-NEXT: ret i32 [[TMP1]]
//
#ifndef __ARM_FEATURE_CRC32
__attribute__((target("crc")))
#endif
uint32_t test_crc32b(uint32_t a, uint8_t b) {
return __crc32b(a, b);
}
Expand All @@ -1351,6 +1400,9 @@ uint32_t test_crc32b(uint32_t a, uint8_t b) {
// AArch64-NEXT: [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32h(i32 [[A:%.*]], i32 [[TMP0]])
// AArch64-NEXT: ret i32 [[TMP1]]
//
#ifndef __ARM_FEATURE_CRC32
__attribute__((target("crc")))
#endif
uint32_t test_crc32h(uint32_t a, uint16_t b) {
return __crc32h(a, b);
}
Expand All @@ -1365,6 +1417,9 @@ uint32_t test_crc32h(uint32_t a, uint16_t b) {
// AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32w(i32 [[A:%.*]], i32 [[B:%.*]])
// AArch64-NEXT: ret i32 [[TMP0]]
//
#ifndef __ARM_FEATURE_CRC32
__attribute__((target("crc")))
#endif
uint32_t test_crc32w(uint32_t a, uint32_t b) {
return __crc32w(a, b);
}
Expand All @@ -1383,6 +1438,9 @@ uint32_t test_crc32w(uint32_t a, uint32_t b) {
// AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32x(i32 [[A:%.*]], i64 [[B:%.*]])
// AArch64-NEXT: ret i32 [[TMP0]]
//
#ifndef __ARM_FEATURE_CRC32
__attribute__((target("crc")))
#endif
uint32_t test_crc32d(uint32_t a, uint64_t b) {
return __crc32d(a, b);
}
Expand All @@ -1399,6 +1457,9 @@ uint32_t test_crc32d(uint32_t a, uint64_t b) {
// AArch64-NEXT: [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32cb(i32 [[A:%.*]], i32 [[TMP0]])
// AArch64-NEXT: ret i32 [[TMP1]]
//
#ifndef __ARM_FEATURE_CRC32
__attribute__((target("crc")))
#endif
uint32_t test_crc32cb(uint32_t a, uint8_t b) {
return __crc32cb(a, b);
}
Expand All @@ -1415,6 +1476,9 @@ uint32_t test_crc32cb(uint32_t a, uint8_t b) {
// AArch64-NEXT: [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32ch(i32 [[A:%.*]], i32 [[TMP0]])
// AArch64-NEXT: ret i32 [[TMP1]]
//
#ifndef __ARM_FEATURE_CRC32
__attribute__((target("crc")))
#endif
uint32_t test_crc32ch(uint32_t a, uint16_t b) {
return __crc32ch(a, b);
}
Expand All @@ -1429,6 +1493,9 @@ uint32_t test_crc32ch(uint32_t a, uint16_t b) {
// AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32cw(i32 [[A:%.*]], i32 [[B:%.*]])
// AArch64-NEXT: ret i32 [[TMP0]]
//
#ifndef __ARM_FEATURE_CRC32
__attribute__((target("crc")))
#endif
uint32_t test_crc32cw(uint32_t a, uint32_t b) {
return __crc32cw(a, b);
}
Expand All @@ -1447,6 +1514,9 @@ uint32_t test_crc32cw(uint32_t a, uint32_t b) {
// AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32cx(i32 [[A:%.*]], i64 [[B:%.*]])
// AArch64-NEXT: ret i32 [[TMP0]]
//
#ifndef __ARM_FEATURE_CRC32
__attribute__((target("crc")))
#endif
uint32_t test_crc32cd(uint32_t a, uint64_t b) {
return __crc32cd(a, b);
}
Expand Down
4 changes: 2 additions & 2 deletions clang/test/CodeGen/debug-info-codeview-buildinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ int main(void) { return 42; }
// DISABLE-NOT: "-cc1"
// DISABLE: 0x{{.+}} | LF_BUILDINFO [size = {{.+}}]
// DISABLE-NEXT: 0x{{.+}}: `{{.*}}`
// DISABLE-NEXT: <no type>: ``
// DISABLE-NEXT: 0x{{.+}}: `{{.*}}`
// DISABLE-NEXT: 0x{{.+}}: `{{.*}}`
// DISABLE-NEXT: 0x{{.+}}: ``
// DISABLE-NEXT: <no type>: ``
// DISABLE-NEXT: 0x{{.+}}: `{{.*}}`

// MESSAGELEN: Types (.debug$T)
// MESSAGELEN: ============================================================
Expand Down
38 changes: 38 additions & 0 deletions clang/test/Driver/codegen-data.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Verify only one of codegen-data flag is passed.
// RUN: not %clang -### -S --target=aarch64-linux-gnu -fcodegen-data-generate -fcodegen-data-use %s 2>&1 | FileCheck %s --check-prefix=CONFLICT
// RUN: not %clang -### -S --target=arm64-apple-darwin -fcodegen-data-generate -fcodegen-data-use %s 2>&1 | FileCheck %s --check-prefix=CONFLICT
// CONFLICT: error: invalid argument '-fcodegen-data-generate' not allowed with '-fcodegen-data-use'

// Verify the codegen-data-generate (boolean) flag is passed to LLVM
// RUN: %clang -### -S --target=aarch64-linux-gnu -fcodegen-data-generate %s 2>&1| FileCheck %s --check-prefix=GENERATE
// RUN: %clang -### -S --target=arm64-apple-darwin -fcodegen-data-generate %s 2>&1| FileCheck %s --check-prefix=GENERATE
// GENERATE: "-mllvm" "-codegen-data-generate"

// Verify the codegen-data-use-path flag (with a default value) is passed to LLVM.
// RUN: %clang -### -S --target=aarch64-linux-gnu -fcodegen-data-use %s 2>&1| FileCheck %s --check-prefix=USE
// RUN: %clang -### -S --target=arm64-apple-darwin -fcodegen-data-use %s 2>&1| FileCheck %s --check-prefix=USE
// RUN: %clang -### -S --target=aarch64-linux-gnu -fcodegen-data-use=file %s 2>&1 | FileCheck %s --check-prefix=USE-FILE
// RUN: %clang -### -S --target=arm64-apple-darwin -fcodegen-data-use=file %s 2>&1 | FileCheck %s --check-prefix=USE-FILE
// USE: "-mllvm" "-codegen-data-use-path=default.cgdata"
// USE-FILE: "-mllvm" "-codegen-data-use-path=file"

// Verify the codegen-data-generate (boolean) flag with a LTO.
// RUN: %clang -### -flto --target=aarch64-linux-gnu -fcodegen-data-generate %s 2>&1 | FileCheck %s --check-prefix=GENERATE-LTO
// GENERATE-LTO: {{ld(.exe)?"}}
// GENERATE-LTO-SAME: "-plugin-opt=-codegen-data-generate"
// RUN: %clang -### -flto --target=arm64-apple-darwin -fcodegen-data-generate %s 2>&1 | FileCheck %s --check-prefix=GENERATE-LTO-DARWIN
// GENERATE-LTO-DARWIN: {{ld(.exe)?"}}
// GENERATE-LTO-DARWIN-SAME: "-mllvm" "-codegen-data-generate"

// Verify the codegen-data-use-path flag with a LTO is passed to LLVM.
// RUN: %clang -### -flto=thin --target=aarch64-linux-gnu -fcodegen-data-use %s 2>&1 | FileCheck %s --check-prefix=USE-LTO
// USE-LTO: {{ld(.exe)?"}}
// USE-LTO-SAME: "-plugin-opt=-codegen-data-use-path=default.cgdata"
// RUN: %clang -### -flto=thin --target=arm64-apple-darwin -fcodegen-data-use %s 2>&1 | FileCheck %s --check-prefix=USE-LTO-DARWIN
// USE-LTO-DARWIN: {{ld(.exe)?"}}
// USE-LTO-DARWIN-SAME: "-mllvm" "-codegen-data-use-path=default.cgdata"

// For now, LLD MachO supports for generating the codegen data at link time.
// RUN: %clang -### -fuse-ld=lld -B%S/Inputs/lld --target=arm64-apple-darwin -fcodegen-data-generate %s 2>&1 | FileCheck %s --check-prefix=GENERATE-LLD-DARWIN
// GENERATE-LLD-DARWIN: {{ld(.exe)?"}}
// GENERATE-LLD-DARWIN-SAME: "--codegen-data-generate-path=default.cgdata"
26 changes: 26 additions & 0 deletions clang/test/Driver/riscv-cpus.c
Original file line number Diff line number Diff line change
Expand Up @@ -502,3 +502,29 @@

// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mtune=syntacore-scr5-rv64 | FileCheck -check-prefix=MTUNE-SYNTACORE-SCR5-RV64 %s
// MTUNE-SYNTACORE-SCR5-RV64: "-tune-cpu" "syntacore-scr5-rv64"

// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=syntacore-scr7 | FileCheck -check-prefix=MCPU-SYNTACORE-SCR7 %s
// MCPU-SYNTACORE-SCR7: "-target-cpu" "syntacore-scr7"
// MCPU-SYNTACORE-SCR7-SAME: "-target-feature" "+m"
// MCPU-SYNTACORE-SCR7-SAME: "-target-feature" "+a"
// MCPU-SYNTACORE-SCR7-SAME: "-target-feature" "+f"
// MCPU-SYNTACORE-SCR7-SAME: "-target-feature" "+d"
// MCPU-SYNTACORE-SCR7-SAME: "-target-feature" "+c"
// MCPU-SYNTACORE-SCR7-SAME: "-target-feature" "+v"
// MCPU-SYNTACORE-SCR7-SAME: "-target-feature" "+zicsr"
// MCPU-SYNTACORE-SCR7-SAME: "-target-feature" "+zifencei"
// MCPU-SYNTACORE-SCR7-SAME: "-target-feature" "+zba"
// MCPU-SYNTACORE-SCR7-SAME: "-target-feature" "+zbb"
// MCPU-SYNTACORE-SCR7-SAME: "-target-feature" "+zbc"
// MCPU-SYNTACORE-SCR7-SAME: "-target-feature" "+zbkb"
// MCPU-SYNTACORE-SCR7-SAME: "-target-feature" "+zbkc"
// MCPU-SYNTACORE-SCR7-SAME: "-target-feature" "+zbkx"
// MCPU-SYNTACORE-SCR7-SAME: "-target-feature" "+zbs"
// MCPU-SYNTACORE-SCR7-SAME: "-target-feature" "+zkn"
// MCPU-SYNTACORE-SCR7-SAME: "-target-feature" "+zknd"
// MCPU-SYNTACORE-SCR7-SAME: "-target-feature" "+zkne"
// MCPU-SYNTACORE-SCR7-SAME: "-target-feature" "+zknh"
// MCPU-SYNTACORE-SCR7-SAME: "-target-abi" "lp64d"

// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mtune=syntacore-scr7 | FileCheck -check-prefix=MTUNE-SYNTACORE-SCR7 %s
// MTUNE-SYNTACORE-SCR7: "-tune-cpu" "syntacore-scr7"
2 changes: 2 additions & 0 deletions clang/test/Misc/target-invalid-cpu-note/riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
// RISCV64-SAME: {{^}}, syntacore-scr3-rv64
// RISCV64-SAME: {{^}}, syntacore-scr4-rv64
// RISCV64-SAME: {{^}}, syntacore-scr5-rv64
// RISCV64-SAME: {{^}}, syntacore-scr7
// RISCV64-SAME: {{^}}, veyron-v1
// RISCV64-SAME: {{^}}, xiangshan-nanhu
// RISCV64-SAME: {{$}}
Expand Down Expand Up @@ -85,6 +86,7 @@
// TUNE-RISCV64-SAME: {{^}}, syntacore-scr3-rv64
// TUNE-RISCV64-SAME: {{^}}, syntacore-scr4-rv64
// TUNE-RISCV64-SAME: {{^}}, syntacore-scr5-rv64
// TUNE-RISCV64-SAME: {{^}}, syntacore-scr7
// TUNE-RISCV64-SAME: {{^}}, veyron-v1
// TUNE-RISCV64-SAME: {{^}}, xiangshan-nanhu
// TUNE-RISCV64-SAME: {{^}}, generic
Expand Down
1 change: 1 addition & 0 deletions clang/test/Modules/cxx20-10-3-ex1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ module M:PartImpl;
export module M;
// error: exported partition :Part is an implementation unit
export import :PartImpl; // expected-error {{module partition implementations cannot be exported}}
// expected-warning@-1 {{importing an implementation partition unit in a module interface is not recommended.}}

//--- std10-3-ex1-tu3.cpp
export module M:Part;
Expand Down
6 changes: 6 additions & 0 deletions clang/test/Parser/static_assert.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -triple=x86_64-linux -std=c++2a -verify=cxx2a %s
// RUN: %clang_cc1 -fsyntax-only -triple=x86_64-linux -std=c++2c -verify=cxx2c %s

static_assert(true, "" // cxx2a-warning {{'static_assert' with a user-generated message is a C++26 extension}} \
// cxx2a-note {{to match this '('}} cxx2c-note {{to match this '('}}
// cxx2a-error {{expected ')'}} cxx2c-error {{expected ')'}}
8 changes: 4 additions & 4 deletions clang/test/Sema/diagnose_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

#define _diagnose_if(...) __attribute__((diagnose_if(__VA_ARGS__)))

void failure1(void) _diagnose_if(); // expected-error{{exactly 3 arguments}}
void failure2(void) _diagnose_if(0); // expected-error{{exactly 3 arguments}}
void failure3(void) _diagnose_if(0, ""); // expected-error{{exactly 3 arguments}}
void failure4(void) _diagnose_if(0, "", "error", 1); // expected-error{{exactly 3 arguments}}
void failure1(void) _diagnose_if(); // expected-error{{at least 3 arguments}}
void failure2(void) _diagnose_if(0); // expected-error{{at least 3 arguments}}
void failure3(void) _diagnose_if(0, ""); // expected-error{{at least 3 arguments}}
void failure4(void) _diagnose_if(0, "", "error", 1); // expected-error{{expected string literal as argument}}
void failure5(void) _diagnose_if(0, 0, "error"); // expected-error{{expected string literal as argument of 'diagnose_if' attribute}}
void failure6(void) _diagnose_if(0, "", "invalid"); // expected-error{{invalid diagnostic type for 'diagnose_if'; use "error" or "warning" instead}}
void failure7(void) _diagnose_if(0, "", "ERROR"); // expected-error{{invalid diagnostic type}}
Expand Down
34 changes: 34 additions & 0 deletions clang/test/Sema/warn-lifetime-analysis-nocfg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -553,3 +553,37 @@ void test() {
std::string_view svjkk1 = ReturnStringView(StrCat("bar", "x")); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}}
}
} // namespace GH100549

namespace GH108272 {
template <typename T>
struct [[gsl::Owner]] StatusOr {
const T &value() [[clang::lifetimebound]];
};

template <typename V>
class Wrapper1 {
public:
operator V() const;
V value;
};
std::string_view test1() {
StatusOr<Wrapper1<std::string_view>> k;
// Be conservative in this case, as there is not enough information available
// to infer the lifetime relationship for the Wrapper1 type.
std::string_view good = StatusOr<Wrapper1<std::string_view>>().value();
return k.value();
}

template <typename V>
class Wrapper2 {
public:
operator V() const [[clang::lifetimebound]];
V value;
};
std::string_view test2() {
StatusOr<Wrapper2<std::string_view>> k;
// We expect dangling issues as the conversion operator is lifetimebound。
std::string_view bad = StatusOr<Wrapper2<std::string_view>>().value(); // expected-warning {{temporary whose address is used as value of}}
return k.value(); // expected-warning {{address of stack memory associated}}
}
} // namespace GH108272
63 changes: 63 additions & 0 deletions clang/test/SemaCXX/diagnose_if-warning-group.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// RUN: %clang_cc1 %s -verify=expected,wall -fno-builtin -Wno-pedantic -Werror=comment -Wno-error=abi -Wfatal-errors=assume -Wno-fatal-errors=assume -Wno-format
// RUN: %clang_cc1 %s -verify=expected,wno-all,pedantic,format -fno-builtin -Wno-all -Werror=comment -Wno-error=abi -Werror=assume -Wformat

#define diagnose_if(...) __attribute__((diagnose_if(__VA_ARGS__)))

#ifndef EMTY_WARNING_GROUP
void bougus_warning() diagnose_if(true, "oh no", "warning", "bogus warning") {} // expected-error {{unknown warning group 'bogus warning'}}

void show_in_system_header() diagnose_if(true, "oh no", "warning", "assume", "Banane") {} // expected-error {{'diagnose_if' attribute takes no more than 4 arguments}}
#endif // EMTY_WARNING_GROUP

template <bool b>
void diagnose_if_wcomma() diagnose_if(b, "oh no", "warning", "comma") {}

template <bool b>
void diagnose_if_wcomment() diagnose_if(b, "oh no", "warning", "comment") {}

void empty_warning_group() diagnose_if(true, "oh no", "warning", "") {} // expected-error {{unknown warning group ''}}
void empty_warning_group_error() diagnose_if(true, "oh no", "error", "") {} // expected-error {{unknown warning group ''}}

void diagnose_if_wabi_default_error() diagnose_if(true, "ABI stuff", "error", "abi") {}
void diagnose_assume() diagnose_if(true, "Assume diagnostic", "warning", "assume") {}

void Wall() diagnose_if(true, "oh no", "warning", "all") {}
void Wpedantic() diagnose_if(true, "oh no", "warning", "pedantic") {}
void Wformat_extra_args() diagnose_if(true, "oh no", "warning", "format-extra-args") {}

void call() {
diagnose_if_wcomma<true>(); // expected-warning {{oh no}}
diagnose_if_wcomma<false>();
diagnose_if_wcomment<true>(); // expected-error {{oh no}}
diagnose_if_wcomment<false>();

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wcomma"
diagnose_if_wcomma<true>();
diagnose_if_wcomment<true>(); // expected-error {{oh no}}
#pragma clang diagnostic pop

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wcomment"
diagnose_if_wcomma<true>(); // expected-warning {{oh no}}
diagnose_if_wcomment<true>();
#pragma clang diagnostic pop

diagnose_if_wcomma<true>(); // expected-warning {{oh no}}
diagnose_if_wcomment<true>(); // expected-error {{oh no}}

diagnose_if_wabi_default_error(); // expected-warning {{ABI stuff}}
diagnose_assume(); // expected-error {{Assume diagnostic}}

// Make sure that the -Wassume diagnostic isn't fatal
diagnose_if_wabi_default_error(); // expected-warning {{ABI stuff}}

Wall(); // wall-warning {{oh no}}
Wpedantic(); // pedantic-warning {{oh no}}
Wformat_extra_args(); // format-warning {{oh no}}

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat"
Wformat_extra_args();
#pragma clang diagnostic pop
}
4 changes: 3 additions & 1 deletion clang/test/SemaOpenCL/unsupported.cl
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,7 @@ void no_vla(int n) {
}

void no_logxor(int n) {
int logxor = n ^^ n; // expected-error {{^^ is a reserved operator in OpenCL}}
int logxor = n ^^ n; // expected-error {{^^ is a reserved operator in OpenCL}} \
expected-error {{type name requires a specifier or qualifier}} \
expected-error {{expected expression}}
}
10 changes: 10 additions & 0 deletions clang/test/SemaTemplate/cwg2398.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,3 +379,13 @@ namespace regression1 {
bar(input);
}
} // namespace regression1

namespace regression2 {
template <class> struct D {};

template <class ET, template <class> class VT>
struct D<VT<ET>>;

template <typename, int> struct Matrix;
template struct D<Matrix<double, 3>>;
} // namespace regression2
2 changes: 0 additions & 2 deletions clang/tools/clang-refactor/ClangRefactor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,6 @@ class ClangRefactorTool {
<< "' can't be invoked with the given arguments:\n";
for (const auto &Opt : MissingOptions)
OS << " missing '-" << Opt.getKey() << "' option\n";
OS.flush();
return llvm::make_error<llvm::StringError>(
Error, llvm::inconvertibleErrorCode());
}
Expand Down Expand Up @@ -591,7 +590,6 @@ class ClangRefactorTool {
OS << "note: the following actions are supported:\n";
for (const auto &Subcommand : SubCommands)
OS.indent(2) << Subcommand->getName() << "\n";
OS.flush();
return llvm::make_error<llvm::StringError>(
Error, llvm::inconvertibleErrorCode());
}
Expand Down
7 changes: 3 additions & 4 deletions clang/tools/diagtool/ListWarnings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ int ListWarnings::run(unsigned int argc, char **argv, llvm::raw_ostream &out) {
for (const DiagnosticRecord &DR : getBuiltinDiagnosticsByName()) {
const unsigned diagID = DR.DiagID;

if (DiagnosticIDs::isBuiltinNote(diagID))
if (DiagnosticIDs{}.isNote(diagID))
continue;

if (!DiagnosticIDs::isBuiltinWarningOrExtension(diagID))
if (!DiagnosticIDs{}.isWarningOrExtension(diagID))
continue;

Entry entry(DR.getName(), DiagnosticIDs::getWarningOptionForDiag(diagID));
Entry entry(DR.getName(), DiagnosticIDs{}.getWarningOptionForDiag(diagID));

if (entry.Flag.empty())
Unflagged.push_back(entry);
Expand Down Expand Up @@ -97,4 +97,3 @@ int ListWarnings::run(unsigned int argc, char **argv, llvm::raw_ostream &out) {

return 0;
}

6 changes: 3 additions & 3 deletions clang/tools/diagtool/ShowEnabledWarnings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,18 +117,18 @@ int ShowEnabledWarnings::run(unsigned int argc, char **argv, raw_ostream &Out) {
for (const DiagnosticRecord &DR : getBuiltinDiagnosticsByName()) {
unsigned DiagID = DR.DiagID;

if (DiagnosticIDs::isBuiltinNote(DiagID))
if (DiagnosticIDs{}.isNote(DiagID))
continue;

if (!DiagnosticIDs::isBuiltinWarningOrExtension(DiagID))
if (!DiagnosticIDs{}.isWarningOrExtension(DiagID))
continue;

DiagnosticsEngine::Level DiagLevel =
Diags->getDiagnosticLevel(DiagID, SourceLocation());
if (DiagLevel == DiagnosticsEngine::Ignored)
continue;

StringRef WarningOpt = DiagnosticIDs::getWarningOptionForDiag(DiagID);
StringRef WarningOpt = DiagnosticIDs{}.getWarningOptionForDiag(DiagID);
Active.push_back(PrettyDiag(DR.getName(), WarningOpt, DiagLevel));
}

Expand Down
4 changes: 2 additions & 2 deletions clang/tools/driver/cc1gen_reproducer_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ static std::string generateReproducerMetaInfo(const ClangInvocationInfo &Info) {
OS << '}';
// FIXME: Compare unsaved file hashes and report mismatch in the reproducer.
if (Info.Dump)
llvm::outs() << "REPRODUCER METAINFO: " << OS.str() << "\n";
return std::move(OS.str());
llvm::outs() << "REPRODUCER METAINFO: " << Result << "\n";
return Result;
}

/// Generates a reproducer for a set of arguments from a specific invocation.
Expand Down
4 changes: 3 additions & 1 deletion clang/tools/libclang/CXStoredDiagnostic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ CXString CXStoredDiagnostic::getSpelling() const {

CXString CXStoredDiagnostic::getDiagnosticOption(CXString *Disable) const {
unsigned ID = Diag.getID();
StringRef Option = DiagnosticIDs::getWarningOptionForDiag(ID);
if (DiagnosticIDs::IsCustomDiag(ID))
return cxstring::createEmpty();
StringRef Option = DiagnosticIDs{}.getWarningOptionForDiag(ID);
if (!Option.empty()) {
if (Disable)
*Disable = cxstring::createDup((Twine("-Wno-") + Option).str());
Expand Down
2 changes: 1 addition & 1 deletion clang/unittests/AST/SourceLocationTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class WhileParenLocationVerifier : public MatchVerifier<WhileStmt> {
RParenLoc.print(Msg, *Result.SourceManager);
Msg << ">";

this->setFailure(Msg.str());
this->setFailure(MsgStr);
}
}
};
Expand Down
2 changes: 1 addition & 1 deletion clang/unittests/AST/TemplateNameTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ std::string printTemplateName(TemplateName TN, const PrintingPolicy &Policy,
std::string Result;
llvm::raw_string_ostream Out(Result);
TN.print(Out, Policy, Qual);
return Out.str();
return Result;
}

TEST(TemplateName, PrintTemplate) {
Expand Down
2 changes: 1 addition & 1 deletion clang/unittests/Analysis/ExprMutationAnalyzerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ mutatedBy(const SmallVectorImpl<BoundNodes> &Results, ASTUnit *AST) {
std::string Buffer;
llvm::raw_string_ostream Stream(Buffer);
By->printPretty(Stream, nullptr, AST->getASTContext().getPrintingPolicy());
Chain.emplace_back(StringRef(Stream.str()).trim().str());
Chain.emplace_back(StringRef(Buffer).trim().str());
E = dyn_cast<DeclRefExpr>(By);
}
return Chain;
Expand Down
7 changes: 6 additions & 1 deletion clang/unittests/Format/FormatTestJS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -579,12 +579,17 @@ TEST_F(FormatTestJS, GoogScopes) {
"});");
}

TEST_F(FormatTestJS, GoogAnonymousClass) {
TEST_F(FormatTestJS, ClassExtends) {
verifyFormat("a = class extends goog.structs.a {\n"
" a() {\n"
" return 0;\n"
" }\n"
"};");
verifyFormat("a = class Foo extends goog.structs.a {\n"
" a() {\n"
" return 0;\n"
" }\n"
"};");
}

TEST_F(FormatTestJS, IIFEs) {
Expand Down
Loading