Skip to content

Commit

Permalink
merge main into amd-staging
Browse files Browse the repository at this point in the history
Change-Id: I10e62201bd8794d01b32d0146a72ab862b39cebe
  • Loading branch information
Jenkins committed Feb 18, 2024
2 parents c164257 + 536d78c commit c232c71
Show file tree
Hide file tree
Showing 24 changed files with 796 additions and 485 deletions.
84 changes: 48 additions & 36 deletions clang/include/clang/Basic/Attr.td

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion clang/lib/AST/Interp/ByteCodeExprGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1468,7 +1468,7 @@ bool ByteCodeExprGen<Emitter>::VisitCompoundAssignOperator(
std::optional<PrimType> LHSComputationT =
classify(E->getComputationLHSType());
std::optional<PrimType> LT = classify(LHS->getType());
std::optional<PrimType> RT = classify(E->getComputationResultType());
std::optional<PrimType> RT = classify(RHS->getType());
std::optional<PrimType> ResultT = classify(E->getType());

if (!LT || !RT || !ResultT || !LHSComputationT)
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/AST/Interp/Descriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ static void moveArrayDesc(Block *B, const std::byte *Src, std::byte *Dst,
static void ctorRecord(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
bool IsActive, const Descriptor *D) {
const bool IsUnion = D->ElemRecord->isUnion();
auto CtorSub = [=](unsigned SubOff, Descriptor *F, bool IsBase) {
auto CtorSub = [=](unsigned SubOff, const Descriptor *F, bool IsBase) {
auto *Desc = reinterpret_cast<InlineDescriptor *>(Ptr + SubOff) - 1;
Desc->Offset = SubOff;
Desc->Desc = F;
Expand All @@ -161,7 +161,7 @@ static void ctorRecord(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
}

static void dtorRecord(Block *B, std::byte *Ptr, const Descriptor *D) {
auto DtorSub = [=](unsigned SubOff, Descriptor *F) {
auto DtorSub = [=](unsigned SubOff, const Descriptor *F) {
if (auto Fn = F->DtorFn)
Fn(B, Ptr + SubOff, F);
};
Expand Down
43 changes: 26 additions & 17 deletions clang/lib/AST/Interp/Program.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,8 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
unsigned VirtSize = 0;

// Helper to get a base descriptor.
auto GetBaseDesc = [this](const RecordDecl *BD, Record *BR) -> Descriptor * {
auto GetBaseDesc = [this](const RecordDecl *BD,
const Record *BR) -> const Descriptor * {
if (!BR)
return nullptr;
return allocateDescriptor(BD, BR, std::nullopt, /*isConst=*/false,
Expand All @@ -258,31 +259,39 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
// Reserve space for base classes.
Record::BaseList Bases;
Record::VirtualBaseList VirtBases;
if (auto *CD = dyn_cast<CXXRecordDecl>(RD)) {
if (const auto *CD = dyn_cast<CXXRecordDecl>(RD)) {

for (const CXXBaseSpecifier &Spec : CD->bases()) {
if (Spec.isVirtual())
continue;

const RecordDecl *BD = Spec.getType()->castAs<RecordType>()->getDecl();
Record *BR = getOrCreateRecord(BD);
if (Descriptor *Desc = GetBaseDesc(BD, BR)) {
BaseSize += align(sizeof(InlineDescriptor));
Bases.push_back({BD, BaseSize, Desc, BR});
BaseSize += align(BR->getSize());
continue;
// In error cases, the base might not be a RecordType.
if (const auto *RT = Spec.getType()->getAs<RecordType>()) {
const RecordDecl *BD = RT->getDecl();
const Record *BR = getOrCreateRecord(BD);

if (const Descriptor *Desc = GetBaseDesc(BD, BR)) {
BaseSize += align(sizeof(InlineDescriptor));
Bases.push_back({BD, BaseSize, Desc, BR});
BaseSize += align(BR->getSize());
continue;
}
}
return nullptr;
}

for (const CXXBaseSpecifier &Spec : CD->vbases()) {
const RecordDecl *BD = Spec.getType()->castAs<RecordType>()->getDecl();
Record *BR = getOrCreateRecord(BD);

if (Descriptor *Desc = GetBaseDesc(BD, BR)) {
VirtSize += align(sizeof(InlineDescriptor));
VirtBases.push_back({BD, VirtSize, Desc, BR});
VirtSize += align(BR->getSize());
continue;
if (const auto *RT = Spec.getType()->getAs<RecordType>()) {
const RecordDecl *BD = RT->getDecl();
const Record *BR = getOrCreateRecord(BD);

if (const Descriptor *Desc = GetBaseDesc(BD, BR)) {
VirtSize += align(sizeof(InlineDescriptor));
VirtBases.push_back({BD, VirtSize, Desc, BR});
VirtSize += align(BR->getSize());
continue;
}
}
return nullptr;
}
Expand All @@ -298,7 +307,7 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
QualType FT = FD->getType();
const bool IsConst = FT.isConstQualified();
const bool IsMutable = FD->isMutable();
Descriptor *Desc;
const Descriptor *Desc;
if (std::optional<PrimType> T = Ctx.classify(FT)) {
Desc = createDescriptor(FD, *T, std::nullopt, IsConst,
/*isTemporary=*/false, IsMutable);
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/AST/Interp/Record.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,16 @@ class Record final {
struct Field {
const FieldDecl *Decl;
unsigned Offset;
Descriptor *Desc;
const Descriptor *Desc;
bool isBitField() const { return Decl->isBitField(); }
};

/// Describes a base class.
struct Base {
const RecordDecl *Decl;
unsigned Offset;
Descriptor *Desc;
Record *R;
const Descriptor *Desc;
const Record *R;
};

/// Mapping from identifiers to field descriptors.
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ static bool attributeHasIdentifierArg(const IdentifierInfo &II) {

/// Determine whether the given attribute has an identifier argument.
static ParsedAttributeArgumentsProperties
attributeStringLiteralListArg(const IdentifierInfo &II) {
attributeStringLiteralListArg(const llvm::Triple &T, const IdentifierInfo &II) {
#define CLANG_ATTR_STRING_LITERAL_ARG_LIST
return llvm::StringSwitch<uint32_t>(normalizeAttrName(II.getName()))
#include "clang/Parse/AttrParserStringSwitches.inc"
Expand Down Expand Up @@ -550,7 +550,7 @@ unsigned Parser::ParseAttributeArgsCommon(

ExprVector ParsedExprs;
ParsedAttributeArgumentsProperties ArgProperties =
attributeStringLiteralListArg(*AttrName);
attributeStringLiteralListArg(getTargetInfo().getTriple(), *AttrName);
if (ParseAttributeArgumentList(*AttrName, ParsedExprs, ArgProperties)) {
SkipUntil(tok::r_paren, StopAtSemi);
return 0;
Expand Down
13 changes: 13 additions & 0 deletions clang/test/AST/Interp/crash-GH49103-2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// RUN: %clang_cc1 -verify -std=c++98 %s -fexperimental-new-constant-interpreter
// RUN: %clang_cc1 -verify -std=c++11 %s -fexperimental-new-constant-interpreter
// RUN: %clang_cc1 -verify -std=c++14 %s -fexperimental-new-constant-interpreter
// RUN: %clang_cc1 -verify -std=c++17 %s -fexperimental-new-constant-interpreter
// RUN: %clang_cc1 -verify -std=c++20 %s -fexperimental-new-constant-interpreter
// RUN: %clang_cc1 -verify -std=c++23 %s -fexperimental-new-constant-interpreter
// RUN: %clang_cc1 -verify -std=c++2c %s -fexperimental-new-constant-interpreter

// https://github.com/llvm/llvm-project/issues/49103

template<class> struct A; // expected-note 0+ {{}}
struct S : __make_integer_seq<A, int, 42> { }; // expected-error 0+ {{}}
S s;
9 changes: 9 additions & 0 deletions clang/test/AST/Interp/shifts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,3 +188,12 @@ namespace shifts {
// ref-cxx17-error {{not an integral constant expression}} \
// ref-cxx17-note {{in call to 'foo(2)'}}
};

namespace LongInt {
constexpr int f() {
int a = 1;
a <<= (long)0;
return 1;
}
static_assert(f() == 1, "");
};
2 changes: 1 addition & 1 deletion clang/test/Sema/attr-function-return.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ __attribute__((function_return("thunk-extern"))) void w(void) {}
// expected-warning@+1 {{'function_return' attribute argument not supported: invalid}}
__attribute__((function_return("invalid"))) void v(void) {}

// expected-error@+1 {{'function_return' attribute requires a string}}
// expected-error@+1 {{expected string literal as argument of 'function_return' attribute}}
__attribute__((function_return(5))) void a(void) {}

// expected-error@+1 {{'function_return' attribute takes one argument}}
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Sema/callingconv-iamcu.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ int __attribute__((pcs("aapcs", "aapcs"))) pcs1(void); // expected-error {{'pcs'
int __attribute__((pcs())) pcs2(void); // expected-error {{'pcs' attribute takes one argument}}
int __attribute__((pcs(pcs1))) pcs3(void); // expected-error {{'pcs' attribute requires a string}} \
// expected-error {{invalid PCS type}}
int __attribute__((pcs(0))) pcs4(void); // expected-error {{'pcs' attribute requires a string}}
int __attribute__((pcs(0))) pcs4(void); // expected-error {{expected string literal as argument of 'pcs' attribute}}
/* These are ignored because the target is i386 and not ARM */
int __attribute__((pcs("aapcs"))) pcs5(void); // expected-warning {{'pcs' calling convention is not supported for this target}}
int __attribute__((pcs("aapcs-vfp"))) pcs6(void); // expected-warning {{'pcs' calling convention is not supported for this target}}
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Sema/callingconv.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ int __attribute__((pcs("aapcs", "aapcs"))) pcs1(void); // expected-error {{'pcs'
int __attribute__((pcs())) pcs2(void); // expected-error {{'pcs' attribute takes one argument}}
int __attribute__((pcs(pcs1))) pcs3(void); // expected-error {{'pcs' attribute requires a string}} \
// expected-error {{invalid PCS type}}
int __attribute__((pcs(0))) pcs4(void); // expected-error {{'pcs' attribute requires a string}}
int __attribute__((pcs(0))) pcs4(void); // expected-error {{expected string literal as argument of 'pcs' attribute}}
/* These are ignored because the target is i386 and not ARM */
int __attribute__((pcs("aapcs"))) pcs5(void); // expected-warning {{'pcs' calling convention is not supported for this target}}
int __attribute__((pcs("aapcs-vfp"))) pcs6(void); // expected-warning {{'pcs' calling convention is not supported for this target}}
Expand Down
1 change: 1 addition & 0 deletions clang/test/Sema/mips-interrupt-attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ struct a { int b; };

struct a test __attribute__((interrupt)); // expected-warning {{'interrupt' attribute only applies to functions and methods}}

__attribute((interrupt(42))) void foo0(void) {} // expected-error {{expected string literal as argument of 'interrupt' attribute}}
__attribute__((interrupt("EIC"))) void foo1(void) {} // expected-warning {{'interrupt' attribute argument not supported: 'EIC'}}

__attribute__((interrupt("eic", 1))) void foo2(void) {} // expected-error {{'interrupt' attribute takes no more than 1 argument}}
Expand Down
1 change: 1 addition & 0 deletions clang/test/Sema/riscv-interrupt-attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ struct a { int b; };

struct a test __attribute__((interrupt)); // expected-warning {{'interrupt' attribute only applies to functions}}

__attribute__((interrupt(42))) void foo0(void) {} // expected-error {{expected string literal as argument of 'interrupt' attribute}}
__attribute__((interrupt("USER"))) void foo1(void) {} // expected-warning {{'interrupt' attribute argument not supported: USER}}
__attribute__((interrupt("user"))) void foo1b(void) {} // expected-warning {{'interrupt' attribute argument not supported: user}}
__attribute__((interrupt("MACHINE"))) void foo1c(void) {} // expected-warning {{'interrupt' attribute argument not supported: MACHINE}}
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Sema/zero_call_used_regs.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

void failure1(void) _zero_call_used_regs(); // expected-error {{takes one argument}}
void failure2(void) _zero_call_used_regs("used", "used-gpr"); // expected-error {{takes one argument}}
void failure3(void) _zero_call_used_regs(0); // expected-error {{requires a string}}
void failure3(void) _zero_call_used_regs(0); // expected-error {{expected string literal}}
void failure4(void) _zero_call_used_regs("hello"); // expected-warning {{argument not supported: hello}}

void success1(void) _zero_call_used_regs("skip");
Expand Down
2 changes: 1 addition & 1 deletion clang/test/SemaCXX/warn-consumed-parsing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ void function3() CONSUMABLE(consumed); // expected-warning {{'consumable' attrib

class CONSUMABLE(unknown) AttrTester1 {
void callableWhen0() CALLABLE_WHEN("unconsumed");
void callableWhen1() CALLABLE_WHEN(42); // expected-error {{'callable_when' attribute requires a string}}
void callableWhen1() CALLABLE_WHEN(42); // expected-error {{expected string literal as argument of 'callable_when' attribute}}
void callableWhen2() CALLABLE_WHEN("foo"); // expected-warning {{'callable_when' attribute argument not supported: foo}}
void callableWhen3() CALLABLE_WHEN(unconsumed);
void consumes() SET_TYPESTATE(consumed);
Expand Down
4 changes: 2 additions & 2 deletions clang/test/SemaHLSL/shader_type_attr.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ int forwardDecl() {

// expected-error@+1 {{'shader' attribute takes one argument}}
[shader()]
// expected-error@+1 {{'shader' attribute takes one argument}}
// expected-error@+1 {{expected string literal as argument of 'shader' attribute}}
[shader(1, 2)]
// expected-error@+1 {{'shader' attribute requires a string}}
// expected-error@+1 {{expected string literal as argument of 'shader' attribute}}
[shader(1)]
// expected-warning@+1 {{'shader' attribute argument not supported: cs}}
[shader("cs")]
Expand Down
80 changes: 63 additions & 17 deletions clang/utils/TableGen/ClangAttrEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,13 @@ static StringRef NormalizeGNUAttrSpelling(StringRef AttrSpelling) {
typedef std::vector<std::pair<std::string, const Record *>> ParsedAttrMap;

static ParsedAttrMap getParsedAttrList(const RecordKeeper &Records,
ParsedAttrMap *Dupes = nullptr) {
ParsedAttrMap *Dupes = nullptr,
bool SemaOnly = true) {
std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
std::set<std::string> Seen;
ParsedAttrMap R;
for (const auto *Attr : Attrs) {
if (Attr->getValueAsBit("SemaHandler")) {
if (!SemaOnly || Attr->getValueAsBit("SemaHandler")) {
std::string AN;
if (Attr->isSubClassOf("TargetSpecificAttr") &&
!Attr->isValueUnset("ParseKind")) {
Expand Down Expand Up @@ -2358,19 +2359,21 @@ static bool isVariadicExprArgument(const Record *Arg) {
}

static bool isStringLiteralArgument(const Record *Arg) {
return !Arg->getSuperClasses().empty() &&
llvm::StringSwitch<bool>(
Arg->getSuperClasses().back().first->getName())
.Case("StringArgument", true)
.Default(false);
if (Arg->getSuperClasses().empty())
return false;
StringRef ArgKind = Arg->getSuperClasses().back().first->getName();
if (ArgKind == "EnumArgument")
return Arg->getValueAsBit("IsString");
return ArgKind == "StringArgument";
}

static bool isVariadicStringLiteralArgument(const Record *Arg) {
return !Arg->getSuperClasses().empty() &&
llvm::StringSwitch<bool>(
Arg->getSuperClasses().back().first->getName())
.Case("VariadicStringArgument", true)
.Default(false);
if (Arg->getSuperClasses().empty())
return false;
StringRef ArgKind = Arg->getSuperClasses().back().first->getName();
if (ArgKind == "VariadicEnumArgument")
return Arg->getValueAsBit("IsString");
return ArgKind == "VariadicStringArgument";
}

static void emitClangAttrVariadicIdentifierArgList(RecordKeeper &Records,
Expand All @@ -2393,14 +2396,18 @@ static void emitClangAttrVariadicIdentifierArgList(RecordKeeper &Records,
OS << "#endif // CLANG_ATTR_VARIADIC_IDENTIFIER_ARG_LIST\n\n";
}

static bool GenerateTargetSpecificAttrChecks(const Record *R,
std::vector<StringRef> &Arches,
std::string &Test,
std::string *FnName);

// Emits the list of arguments that should be parsed as unevaluated string
// literals for each attribute.
static void emitClangAttrUnevaluatedStringLiteralList(RecordKeeper &Records,
raw_ostream &OS) {
OS << "#if defined(CLANG_ATTR_STRING_LITERAL_ARG_LIST)\n";
std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr");
for (const auto *Attr : Attrs) {
std::vector<Record *> Args = Attr->getValueAsListOfDefs("Args");

auto MakeMask = [](ArrayRef<Record *> Args) {
uint32_t Bits = 0;
assert(Args.size() <= 32 && "unsupported number of arguments in attribute");
for (uint32_t N = 0; N < Args.size(); ++N) {
Expand All @@ -2411,11 +2418,46 @@ static void emitClangAttrUnevaluatedStringLiteralList(RecordKeeper &Records,
break;
}
}
if (!Bits)
return Bits;
};

auto AddMaskWithTargetCheck = [](const Record *Attr, uint32_t Mask,
std::string &MaskStr) {
const Record *T = Attr->getValueAsDef("Target");
std::vector<StringRef> Arches = T->getValueAsListOfStrings("Arches");
std::string Test;
GenerateTargetSpecificAttrChecks(T, Arches, Test, nullptr);
MaskStr.append(Test + " ? " + std::to_string(Mask) + " : ");
};

ParsedAttrMap Dupes;
ParsedAttrMap Attrs = getParsedAttrList(Records, &Dupes, /*SemaOnly=*/false);
for (const auto &[AttrName, Attr] : Attrs) {
std::string MaskStr;
if (Attr->isSubClassOf("TargetSpecificAttr") &&
!Attr->isValueUnset("ParseKind")) {
if (uint32_t Mask = MakeMask(Attr->getValueAsListOfDefs("Args")))
AddMaskWithTargetCheck(Attr, Mask, MaskStr);
StringRef ParseKind = Attr->getValueAsString("ParseKind");
for (const auto &[DupeParseKind, DupAttr] : Dupes) {
if (DupeParseKind != ParseKind)
continue;
if (uint32_t Mask = MakeMask(DupAttr->getValueAsListOfDefs("Args")))
AddMaskWithTargetCheck(DupAttr, Mask, MaskStr);
}
if (!MaskStr.empty())
MaskStr.append("0");
} else {
if (uint32_t Mask = MakeMask(Attr->getValueAsListOfDefs("Args")))
MaskStr = std::to_string(Mask);
}

if (MaskStr.empty())
continue;

// All these spellings have at least one string literal has argument.
forEachUniqueSpelling(*Attr, [&](const FlattenedSpelling &S) {
OS << ".Case(\"" << S.name() << "\", " << Bits << ")\n";
OS << ".Case(\"" << S.name() << "\", " << MaskStr << ")\n";
});
}
OS << "#endif // CLANG_ATTR_STRING_LITERAL_ARG_LIST\n\n";
Expand Down Expand Up @@ -3404,6 +3446,8 @@ void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS) {
OS << " }\n";
}

} // namespace clang

// Helper function for GenerateTargetSpecificAttrChecks that alters the 'Test'
// parameter with only a single check type, if applicable.
static bool GenerateTargetSpecificAttrCheck(const Record *R, std::string &Test,
Expand Down Expand Up @@ -3570,6 +3614,8 @@ static void GenerateHasAttrSpellingStringSwitch(
OS << " .Default(0);\n";
}

namespace clang {

// Emits list of regular keyword attributes with info about their arguments.
void EmitClangRegularKeywordAttributeInfo(RecordKeeper &Records,
raw_ostream &OS) {
Expand Down
9 changes: 5 additions & 4 deletions libcxx/include/istream
Original file line number Diff line number Diff line change
Expand Up @@ -1010,17 +1010,18 @@ basic_istream<_CharT, _Traits>& basic_istream<_CharT, _Traits>::unget() {
template <class _CharT, class _Traits>
int basic_istream<_CharT, _Traits>::sync() {
ios_base::iostate __state = ios_base::goodbit;
int __r = 0;
sentry __sen(*this, true);
if (this->rdbuf() == nullptr)
return -1;

int __r = 0;
if (__sen) {
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
try {
#endif // _LIBCPP_HAS_NO_EXCEPTIONS
if (this->rdbuf() == nullptr)
return -1;
if (this->rdbuf()->pubsync() == -1) {
__state |= ios_base::badbit;
return -1;
__r = -1;
}
#ifndef _LIBCPP_HAS_NO_EXCEPTIONS
} catch (...) {
Expand Down
Loading

0 comments on commit c232c71

Please sign in to comment.