Skip to content

Commit 3f1657b

Browse files
authored
merge main into amd-staging (llvm#1059)
2 parents ed3f257 + 072fa6d commit 3f1657b

File tree

203 files changed

+5784
-5417
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

203 files changed

+5784
-5417
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ C Language Changes
111111

112112
C2y Feature Support
113113
^^^^^^^^^^^^^^^^^^^
114+
- Implemented `WG14 N3411 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3411.pdf>`_
115+
which allows a source file to not end with a newline character. This is still
116+
reported as a conforming extension in earlier language modes.
114117

115118
C23 Feature Support
116119
^^^^^^^^^^^^^^^^^^^
@@ -148,6 +151,7 @@ Adding [[clang::unsafe_buffer_usage]] attribute to a method definition now turns
148151
related warnings within the method body.
149152

150153
- The ``no_sanitize`` attribute now accepts both ``gnu`` and ``clang`` names.
154+
- The ``ext_vector_type(n)`` attribute can now be used as a generic type attribute.
151155
- Clang now diagnoses use of declaration attributes on void parameters. (#GH108819)
152156
- Clang now allows ``__attribute__((model("small")))`` and
153157
``__attribute__((model("large")))`` on non-TLS globals in x86-64 compilations.
@@ -248,6 +252,7 @@ Bug Fixes in This Version
248252

249253
- Clang now outputs correct values when #embed data contains bytes with negative
250254
signed char values (#GH102798).
255+
- Fixed a crash when merging named enumerations in modules (#GH114240).
251256
- Fixed rejects-valid problem when #embed appears in std::initializer_list or
252257
when it can affect template argument deduction (#GH122306).
253258
- Fix crash on code completion of function calls involving partial order of function templates

clang/include/clang/Basic/Attr.td

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1721,17 +1721,10 @@ def EnableIf : InheritableAttr {
17211721
let Documentation = [EnableIfDocs];
17221722
}
17231723

1724-
def ExtVectorType : Attr {
1725-
// This is an OpenCL-related attribute and does not receive a [[]] spelling.
1726-
let Spellings = [GNU<"ext_vector_type">];
1727-
// FIXME: This subject list is wrong; this is a type attribute.
1728-
let Subjects = SubjectList<[TypedefName], ErrorDiag>;
1724+
def ExtVectorType : TypeAttr {
1725+
let Spellings = [Clang<"ext_vector_type">];
17291726
let Args = [ExprArgument<"NumElements">];
1730-
let ASTNode = 0;
1731-
let Documentation = [Undocumented];
1732-
// This is a type attribute with an incorrect subject list, so should not be
1733-
// permitted by #pragma clang attribute.
1734-
let PragmaAttributeSupport = 0;
1727+
let Documentation = [ExtVectorTypeDocs];
17351728
}
17361729

17371730
def FallThrough : StmtAttr {

clang/include/clang/Basic/AttrDocs.td

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,42 @@ template instantiation, so the value for ``T::number`` is known.
11131113
}];
11141114
}
11151115

1116+
def ExtVectorTypeDocs : Documentation {
1117+
let Category = DocCatFunction;
1118+
let Content = [{
1119+
The ext_vector_type(N) attribute specifies that a type is a vector with N
1120+
elements, directly mapping to an LLVM vector type. Originally from OpenCL, it
1121+
allows element access the array subscript operator ``[]``, ``sN`` where ``N`` is
1122+
a hexadecimal value, or ``x``, ``y``, ``z``, ``w`` for graphics-style indexing.
1123+
This attribute enables efficient SIMD operations and is usable in
1124+
general-purpose code.
1125+
1126+
.. code-block:: c++
1127+
1128+
template <typename T, uint32_t N>
1129+
constexpr T simd_reduce(T [[clang::ext_vector_type(N)]] v) {
1130+
static_assert((N & (N - 1)) == 0, "N must be a power of two");
1131+
if constexpr (N == 1) {
1132+
return v[0];
1133+
} else {
1134+
T [[clang::ext_vector_type(N / 2)]] reduced = v.hi + v.lo;
1135+
return simd_reduce(reduced);
1136+
}
1137+
}
1138+
1139+
The vector type also supports swizzling up to sixteen elements. This can be done
1140+
using the object accessors. The OpenCL documentation lists the full list of
1141+
accepted values.
1142+
.. code-block:: c++
1143+
1144+
using f16_x16 = _Float16 __attribute__((ext_vector_type(16)));
1145+
1146+
f16_x16 reverse(f16_x16 v) { return v.sfedcba9876543210; }
1147+
1148+
See the OpenCL documentation for some more complete examples.
1149+
}];
1150+
}
1151+
11161152
def DiagnoseIfDocs : Documentation {
11171153
let Category = DocCatFunction;
11181154
let Content = [{

clang/include/clang/Sema/Sema.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4008,7 +4008,7 @@ class Sema final : public SemaBase {
40084008
/// Perform ODR-like check for C/ObjC when merging tag types from modules.
40094009
/// Differently from C++, actually parse the body and reject / error out
40104010
/// in case of a structural mismatch.
4011-
bool ActOnDuplicateDefinition(Decl *Prev, SkipBodyInfo &SkipBody);
4011+
bool ActOnDuplicateDefinition(Scope *S, Decl *Prev, SkipBodyInfo &SkipBody);
40124012

40134013
typedef void *SkippedDefinitionContext;
40144014

@@ -4132,6 +4132,12 @@ class Sema final : public SemaBase {
41324132
void MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
41334133
LookupResult &OldDecls);
41344134

4135+
/// CleanupMergedEnum - We have just merged the decl 'New' by making another
4136+
/// definition visible.
4137+
/// This method performs any necessary cleanup on the parser state to discard
4138+
/// child nodes from newly parsed decl we are retiring.
4139+
void CleanupMergedEnum(Scope *S, Decl *New);
4140+
41354141
/// MergeFunctionDecl - We just parsed a function 'New' from
41364142
/// declarator D which has the same name and scope as a previous
41374143
/// declaration 'Old'. Figure out how to resolve this situation,

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5167,6 +5167,12 @@ bool Compiler<Emitter>::visitReturnStmt(const ReturnStmt *RS) {
51675167
}
51685168

51695169
template <class Emitter> bool Compiler<Emitter>::visitIfStmt(const IfStmt *IS) {
5170+
auto visitChildStmt = [&](const Stmt *S) -> bool {
5171+
LocalScope<Emitter> SScope(this);
5172+
if (!visitStmt(S))
5173+
return false;
5174+
return SScope.destroyLocals();
5175+
};
51705176
if (auto *CondInit = IS->getInit())
51715177
if (!visitStmt(CondInit))
51725178
return false;
@@ -5175,7 +5181,22 @@ template <class Emitter> bool Compiler<Emitter>::visitIfStmt(const IfStmt *IS) {
51755181
if (!visitDeclStmt(CondDecl))
51765182
return false;
51775183

5178-
// Compile condition.
5184+
// Save ourselves compiling some code and the jumps, etc. if the condition is
5185+
// stataically known to be either true or false. We could look at more cases
5186+
// here, but I think all the ones that actually happen are using a
5187+
// ConstantExpr.
5188+
if (const auto *CE = dyn_cast_if_present<ConstantExpr>(IS->getCond());
5189+
CE && CE->hasAPValueResult() &&
5190+
CE->getResultAPValueKind() == APValue::ValueKind::Int) {
5191+
APSInt Value = CE->getResultAsAPSInt();
5192+
if (Value.getBoolValue())
5193+
return visitChildStmt(IS->getThen());
5194+
else if (const Stmt *Else = IS->getElse())
5195+
return visitChildStmt(Else);
5196+
return true;
5197+
}
5198+
5199+
// Otherwise, compile the condition.
51795200
if (IS->isNonNegatedConsteval()) {
51805201
if (!this->emitIsConstantContext(IS))
51815202
return false;
@@ -5194,35 +5215,20 @@ template <class Emitter> bool Compiler<Emitter>::visitIfStmt(const IfStmt *IS) {
51945215
LabelTy LabelEnd = this->getLabel();
51955216
if (!this->jumpFalse(LabelElse))
51965217
return false;
5197-
{
5198-
LocalScope<Emitter> ThenScope(this);
5199-
if (!visitStmt(IS->getThen()))
5200-
return false;
5201-
if (!ThenScope.destroyLocals())
5202-
return false;
5203-
}
5218+
if (!visitChildStmt(IS->getThen()))
5219+
return false;
52045220
if (!this->jump(LabelEnd))
52055221
return false;
52065222
this->emitLabel(LabelElse);
5207-
{
5208-
LocalScope<Emitter> ElseScope(this);
5209-
if (!visitStmt(Else))
5210-
return false;
5211-
if (!ElseScope.destroyLocals())
5212-
return false;
5213-
}
5223+
if (!visitChildStmt(Else))
5224+
return false;
52145225
this->emitLabel(LabelEnd);
52155226
} else {
52165227
LabelTy LabelEnd = this->getLabel();
52175228
if (!this->jumpFalse(LabelEnd))
52185229
return false;
5219-
{
5220-
LocalScope<Emitter> ThenScope(this);
5221-
if (!visitStmt(IS->getThen()))
5222-
return false;
5223-
if (!ThenScope.destroyLocals())
5224-
return false;
5225-
}
5230+
if (!visitChildStmt(IS->getThen()))
5231+
return false;
52265232
this->emitLabel(LabelEnd);
52275233
}
52285234

clang/lib/AST/TypePrinter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2093,6 +2093,9 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
20932093
case attr::ArmMveStrictPolymorphism:
20942094
OS << "__clang_arm_mve_strict_polymorphism";
20952095
break;
2096+
case attr::ExtVectorType:
2097+
OS << "ext_vector_type";
2098+
break;
20962099
}
20972100
OS << "))";
20982101
}

clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp

Lines changed: 62 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -551,83 +551,92 @@ void transferCallReturningOptional(const CallExpr *E,
551551
setHasValue(*Loc, State.Env.makeAtomicBoolValue(), State.Env);
552552
}
553553

554-
void handleConstMemberCall(const CallExpr *CE,
554+
// Returns true if the const accessor is handled by caching.
555+
// Returns false if we could not cache. We should perform default handling
556+
// in that case.
557+
bool handleConstMemberCall(const CallExpr *CE,
555558
dataflow::RecordStorageLocation *RecordLoc,
556559
const MatchFinder::MatchResult &Result,
557560
LatticeTransferState &State) {
558-
// If the const method returns an optional or reference to an optional.
559-
if (RecordLoc != nullptr && isSupportedOptionalType(CE->getType())) {
560-
const FunctionDecl *DirectCallee = CE->getDirectCallee();
561-
if (DirectCallee == nullptr)
562-
return;
563-
StorageLocation &Loc =
564-
State.Lattice.getOrCreateConstMethodReturnStorageLocation(
565-
*RecordLoc, DirectCallee, State.Env, [&](StorageLocation &Loc) {
566-
setHasValue(cast<RecordStorageLocation>(Loc),
567-
State.Env.makeAtomicBoolValue(), State.Env);
568-
});
569-
if (CE->isGLValue()) {
570-
// If the call to the const method returns a reference to an optional,
571-
// link the call expression to the cached StorageLocation.
572-
State.Env.setStorageLocation(*CE, Loc);
573-
} else {
574-
// If the call to the const method returns an optional by value, we
575-
// need to use CopyRecord to link the optional to the result object
576-
// of the call expression.
577-
auto &ResultLoc = State.Env.getResultObjectLocation(*CE);
578-
copyRecord(cast<RecordStorageLocation>(Loc), ResultLoc, State.Env);
579-
}
580-
return;
581-
}
561+
if (RecordLoc == nullptr)
562+
return false;
582563

583-
// Cache if the const method returns a reference
584-
if (RecordLoc != nullptr && CE->isGLValue()) {
564+
// Cache if the const method returns a reference.
565+
if (CE->isGLValue()) {
585566
const FunctionDecl *DirectCallee = CE->getDirectCallee();
586567
if (DirectCallee == nullptr)
587-
return;
568+
return false;
588569

570+
// Initialize the optional's "has_value" property to true if the type is
571+
// optional, otherwise no-op. If we want to support const ref to pointers or
572+
// bools we should initialize their values here too.
573+
auto Init = [&](StorageLocation &Loc) {
574+
if (isSupportedOptionalType(CE->getType()))
575+
setHasValue(cast<RecordStorageLocation>(Loc),
576+
State.Env.makeAtomicBoolValue(), State.Env);
577+
};
589578
StorageLocation &Loc =
590579
State.Lattice.getOrCreateConstMethodReturnStorageLocation(
591-
*RecordLoc, DirectCallee, State.Env, [&](StorageLocation &Loc) {
592-
// no-op
593-
});
580+
*RecordLoc, DirectCallee, State.Env, Init);
594581

595582
State.Env.setStorageLocation(*CE, Loc);
596-
return;
583+
return true;
597584
}
598-
599-
// Cache if the const method returns a boolean or pointer type.
600-
// We may decide to cache other return types in the future.
601-
if (RecordLoc != nullptr &&
602-
(CE->getType()->isBooleanType() || CE->getType()->isPointerType())) {
585+
// PRValue cases:
586+
if (CE->getType()->isBooleanType() || CE->getType()->isPointerType()) {
587+
// If the const method returns a boolean or pointer type.
603588
Value *Val = State.Lattice.getOrCreateConstMethodReturnValue(*RecordLoc, CE,
604589
State.Env);
605590
if (Val == nullptr)
606-
return;
591+
return false;
607592
State.Env.setValue(*CE, *Val);
608-
return;
593+
return true;
609594
}
610-
611-
// Perform default handling if the call returns an optional
612-
// but wasn't handled above (if RecordLoc is nullptr).
613595
if (isSupportedOptionalType(CE->getType())) {
614-
transferCallReturningOptional(CE, Result, State);
596+
// If the const method returns an optional by value.
597+
const FunctionDecl *DirectCallee = CE->getDirectCallee();
598+
if (DirectCallee == nullptr)
599+
return false;
600+
StorageLocation &Loc =
601+
State.Lattice.getOrCreateConstMethodReturnStorageLocation(
602+
*RecordLoc, DirectCallee, State.Env, [&](StorageLocation &Loc) {
603+
setHasValue(cast<RecordStorageLocation>(Loc),
604+
State.Env.makeAtomicBoolValue(), State.Env);
605+
});
606+
// Use copyRecord to link the optional to the result object of the call
607+
// expression.
608+
auto &ResultLoc = State.Env.getResultObjectLocation(*CE);
609+
copyRecord(cast<RecordStorageLocation>(Loc), ResultLoc, State.Env);
610+
return true;
615611
}
612+
613+
return false;
616614
}
617615

618-
void transferValue_ConstMemberCall(const CXXMemberCallExpr *MCE,
619-
const MatchFinder::MatchResult &Result,
620-
LatticeTransferState &State) {
621-
handleConstMemberCall(
616+
void handleConstMemberCallWithFallbacks(
617+
const CallExpr *CE, dataflow::RecordStorageLocation *RecordLoc,
618+
const MatchFinder::MatchResult &Result, LatticeTransferState &State) {
619+
if (handleConstMemberCall(CE, RecordLoc, Result, State))
620+
return;
621+
// Perform default handling if the call returns an optional, but wasn't
622+
// handled by caching.
623+
if (isSupportedOptionalType(CE->getType()))
624+
transferCallReturningOptional(CE, Result, State);
625+
}
626+
627+
void transferConstMemberCall(const CXXMemberCallExpr *MCE,
628+
const MatchFinder::MatchResult &Result,
629+
LatticeTransferState &State) {
630+
handleConstMemberCallWithFallbacks(
622631
MCE, dataflow::getImplicitObjectLocation(*MCE, State.Env), Result, State);
623632
}
624633

625-
void transferValue_ConstMemberOperatorCall(
626-
const CXXOperatorCallExpr *OCE, const MatchFinder::MatchResult &Result,
627-
LatticeTransferState &State) {
634+
void transferConstMemberOperatorCall(const CXXOperatorCallExpr *OCE,
635+
const MatchFinder::MatchResult &Result,
636+
LatticeTransferState &State) {
628637
auto *RecordLoc = cast_or_null<dataflow::RecordStorageLocation>(
629638
State.Env.getStorageLocation(*OCE->getArg(0)));
630-
handleConstMemberCall(OCE, RecordLoc, Result, State);
639+
handleConstMemberCallWithFallbacks(OCE, RecordLoc, Result, State);
631640
}
632641

633642
void handleNonConstMemberCall(const CallExpr *CE,
@@ -1094,9 +1103,9 @@ auto buildTransferMatchSwitch() {
10941103

10951104
// const accessor calls
10961105
.CaseOfCFGStmt<CXXMemberCallExpr>(isZeroParamConstMemberCall(),
1097-
transferValue_ConstMemberCall)
1106+
transferConstMemberCall)
10981107
.CaseOfCFGStmt<CXXOperatorCallExpr>(isZeroParamConstMemberOperatorCall(),
1099-
transferValue_ConstMemberOperatorCall)
1108+
transferConstMemberOperatorCall)
11001109
// non-const member calls that may modify the state of an object.
11011110
.CaseOfCFGStmt<CXXMemberCallExpr>(isNonConstMemberCall(),
11021111
transferValue_NonConstMemberCall)

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7313,6 +7313,13 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
73137313
getHLSLRuntime().addBuffer(cast<HLSLBufferDecl>(D));
73147314
break;
73157315

7316+
case Decl::OpenACCDeclare:
7317+
EmitOpenACCDeclare(cast<OpenACCDeclareDecl>(D));
7318+
break;
7319+
case Decl::OpenACCRoutine:
7320+
EmitOpenACCRoutine(cast<OpenACCRoutineDecl>(D));
7321+
break;
7322+
73167323
default:
73177324
// Make sure we handled everything we should, every other kind is a
73187325
// non-top-level decl. FIXME: Would be nice to have an isTopLevelDeclKind

clang/lib/CodeGen/CodeGenModule.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1721,9 +1721,11 @@ class CodeGenModule : public CodeGenTypeCache {
17211721
CodeGenFunction *CGF = nullptr);
17221722

17231723
// Emit code for the OpenACC Declare declaration.
1724-
void EmitOpenACCDeclare(const OpenACCDeclareDecl *D, CodeGenFunction *CGF);
1724+
void EmitOpenACCDeclare(const OpenACCDeclareDecl *D,
1725+
CodeGenFunction *CGF = nullptr);
17251726
// Emit code for the OpenACC Routine declaration.
1726-
void EmitOpenACCRoutine(const OpenACCRoutineDecl *D, CodeGenFunction *CGF);
1727+
void EmitOpenACCRoutine(const OpenACCRoutineDecl *D,
1728+
CodeGenFunction *CGF = nullptr);
17271729

17281730
/// Emit a code for requires directive.
17291731
/// \param D Requires declaration

0 commit comments

Comments
 (0)