Skip to content

Commit 71bd694

Browse files
committed
Merge from 'main' to 'sycl-web' (33 commits)
CONFLICT (content): Merge conflict in clang/include/clang/Driver/Options.td
2 parents 5320a42 + 9ee625b commit 71bd694

File tree

108 files changed

+2501
-474
lines changed

Some content is hidden

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

108 files changed

+2501
-474
lines changed

clang/docs/LanguageExtensions.rst

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2360,6 +2360,50 @@ evaluated, so any side effects of the expression will be discarded.
23602360
23612361
Query for this feature with ``__has_builtin(__builtin_assume)``.
23622362
2363+
``__builtin_offsetof``
2364+
----------------------
2365+
2366+
``__builtin_offsetof`` is used to implement the ``offsetof`` macro, which
2367+
calculates the offset (in bytes) to a given member of the given type.
2368+
2369+
**Syntax**:
2370+
2371+
.. code-block:: c++
2372+
2373+
__builtin_offsetof(type-name, member-designator)
2374+
2375+
**Example of Use**:
2376+
2377+
.. code-block:: c++
2378+
2379+
struct S {
2380+
char c;
2381+
int i;
2382+
struct T {
2383+
float f[2];
2384+
} t;
2385+
};
2386+
2387+
const int offset_to_i = __builtin_offsetof(struct S, i);
2388+
const int ext1 = __builtin_offsetof(struct U { int i; }, i); // C extension
2389+
const int ext2 = __builtin_offsetof(struct S, t.f[1]); // C & C++ extension
2390+
2391+
**Description**:
2392+
2393+
This builtin is usable in an integer constant expression which returns a value
2394+
of type ``size_t``. The value returned is the offset in bytes to the subobject
2395+
designated by the member-designator from the beginning of an object of type
2396+
``type-name``. Clang extends the required standard functionality in a few ways:
2397+
2398+
* In C language modes, the first argument may be the definition of a new type.
2399+
Any type declared this way is scoped to the nearest scope containing the call
2400+
to the builtin.
2401+
* The second argument may be a member-designator designated by a series of
2402+
member access expressions using the dot (``.``) operator or array subscript
2403+
expressions.
2404+
2405+
Query for this feature with ``__has_builtin(__builtin_offsetof)``.
2406+
23632407
``__builtin_call_with_static_chain``
23642408
------------------------------------
23652409

clang/docs/ReleaseNotes.rst

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,8 @@ Non-comprehensive list of changes in this release
504504
- Clang can now generate a PCH when using ``-fdelayed-template-parsing`` for
505505
code with templates containing loop hint pragmas, OpenMP pragmas, and
506506
``#pragma unused``.
507-
507+
- Now diagnoses use of a member access expression or array subscript expression
508+
within ``__builtin_offsetof`` and ``offsetof`` as being a Clang extension.
508509

509510
New Compiler Flags
510511
------------------
@@ -684,6 +685,12 @@ C2x Feature Support
684685
va_end(list);
685686
}
686687
688+
- Diagnose type definitions in the ``type`` argument of ``__builtin_offsetof``
689+
as a conforming C extension according to
690+
`WG14 N2350 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm>`_.
691+
Also documents the builtin appropriately. Note, a type definition in C++
692+
continues to be rejected.
693+
687694
C++ Language Changes in Clang
688695
-----------------------------
689696
- Implemented `DR692 <https://wg21.link/cwg692>`_, `DR1395 <https://wg21.link/cwg1395>`_,

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor",
175175
DeleteAbstractNonVirtualDtor]>;
176176
def AbstractFinalClass : DiagGroup<"abstract-final-class">;
177177
def FinalDtorNonFinalClass : DiagGroup<"final-dtor-non-final-class">;
178+
def GNUOffsetofExtensions : DiagGroup<"gnu-offsetof-extensions">;
178179

179180
def CXX11CompatDeprecatedWritableStr :
180181
DiagGroup<"c++11-compat-deprecated-writable-strings">;
@@ -1147,9 +1148,9 @@ def GNU : DiagGroup<"gnu", [GNUAlignofExpression, GNUAnonymousStruct,
11471148
GNUFlexibleArrayUnionMember, GNUFoldingConstant,
11481149
GNUImaginaryConstant, GNUIncludeNext,
11491150
GNULabelsAsValue, GNULineMarker, GNUNullPointerArithmetic,
1150-
GNUPointerArith, RedeclaredClassMember,
1151-
GNURedeclaredEnum, GNUStatementExpression,
1152-
GNUStaticFloatInit,
1151+
GNUOffsetofExtensions, GNUPointerArith,
1152+
RedeclaredClassMember, GNURedeclaredEnum,
1153+
GNUStatementExpression, GNUStaticFloatInit,
11531154
GNUStringLiteralOperatorTemplate, GNUUnionCast,
11541155
GNUVariableSizedTypeNotAtEnd, ZeroLengthArray,
11551156
GNUZeroLineDirective,

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1607,6 +1607,11 @@ def err_import_in_wrong_fragment : Error<
16071607
def err_export_empty : Error<"export declaration cannot be empty">;
16081608
}
16091609

1610+
def ext_offsetof_member_designator : Extension<
1611+
"using %select{a member access expression|an array subscript expression}0 "
1612+
"within '%select{__builtin_offsetof|offsetof}1' is a Clang extension">,
1613+
InGroup<GNUOffsetofExtensions>;
1614+
16101615
let CategoryName = "Generics Issue" in {
16111616

16121617
def err_objc_expected_type_parameter : Error<

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1686,6 +1686,9 @@ def err_type_defined_in_condition : Error<
16861686
"%0 cannot be defined in a condition">;
16871687
def err_type_defined_in_enum : Error<
16881688
"%0 cannot be defined in an enumeration">;
1689+
def ext_type_defined_in_offsetof : Extension<
1690+
"defining a type within '%select{__builtin_offsetof|offsetof}0' is a Clang "
1691+
"extension">, InGroup<GNUOffsetofExtensions>;
16891692

16901693
def note_pure_virtual_function : Note<
16911694
"unimplemented pure virtual method %0 in %1">;

clang/include/clang/Driver/Options.td

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -972,10 +972,10 @@ def fno_bundle_offload_arch : Flag<["-"], "fno-bundle-offload-arch">,
972972
"This allows .o files to contain .bc bundles that are unspecific "
973973
"to a particular arch version.">;
974974
def offload_arch_EQ : Joined<["--"], "offload-arch=">, Flags<[NoXarchOption]>,
975-
HelpText<"CUDA offloading device architecture (e.g. sm_35), or HIP offloading target ID in the form of a "
976-
"device architecture followed by target ID features delimited by a colon. Each target ID feature "
977-
"is a pre-defined string followed by a plus or minus sign (e.g. gfx908:xnack+:sramecc-). May be "
978-
"specified more than once.">;
975+
HelpText<"Specify an offloading device architecture for CUDA, HIP, or OpenMP. (e.g. sm_35). "
976+
"If 'native' is used the compiler will detect locally installed architectures. "
977+
"For HIP offloading, the device architecture can be followed by target ID features "
978+
"delimited by a colon (e.g. gfx908:xnack+:sramecc-). May be specified more than once.">;
979979
def cuda_gpu_arch_EQ : Joined<["--"], "cuda-gpu-arch=">, Flags<[NoXarchOption, CoreOption]>,
980980
Alias<offload_arch_EQ>;
981981
def cuda_feature_EQ : Joined<["--"], "cuda-feature=">, HelpText<"Manually specify the CUDA feature to use">;

clang/include/clang/Parse/Parser.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class Parser : public CodeCompletionHandler {
6262
friend class ColonProtectionRAIIObject;
6363
friend class ParsingOpenMPDirectiveRAII;
6464
friend class InMessageExpressionRAIIObject;
65+
friend class OffsetOfStateRAIIObject;
6566
friend class PoisonSEHIdentifiersRAIIObject;
6667
friend class ObjCDeclContextSwitch;
6768
friend class ParenBraceBracketBalancer;
@@ -248,6 +249,8 @@ class Parser : public CodeCompletionHandler {
248249
/// function call.
249250
bool CalledSignatureHelp = false;
250251

252+
Sema::OffsetOfKind OffsetOfState = Sema::OffsetOfKind::OOK_Outside;
253+
251254
/// The "depth" of the template parameters currently being parsed.
252255
unsigned TemplateParameterDepth;
253256

clang/include/clang/Parse/RAIIObjectsForParser.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,19 @@ namespace clang {
341341
}
342342
};
343343

344+
class OffsetOfStateRAIIObject {
345+
Sema::OffsetOfKind &OffsetOfState;
346+
Sema::OffsetOfKind OldValue;
347+
348+
public:
349+
OffsetOfStateRAIIObject(Parser &P, Sema::OffsetOfKind Value)
350+
: OffsetOfState(P.OffsetOfState), OldValue(P.OffsetOfState) {
351+
OffsetOfState = Value;
352+
}
353+
354+
~OffsetOfStateRAIIObject() { OffsetOfState = OldValue; }
355+
};
356+
344357
/// RAII object that makes sure paren/bracket/brace count is correct
345358
/// after declaration/statement parsing, even when there's a parsing error.
346359
class ParenBraceBracketBalancer {

clang/include/clang/Sema/Sema.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3563,6 +3563,16 @@ class Sema final {
35633563
TUK_Friend // Friend declaration: 'friend struct foo;'
35643564
};
35653565

3566+
enum OffsetOfKind {
3567+
// Not parsing a type within __builtin_offsetof.
3568+
OOK_Outside,
3569+
// Parsing a type within __builtin_offsetof.
3570+
OOK_Builtin,
3571+
// Parsing a type within macro "offsetof", defined in __buitin_offsetof
3572+
// To improve our diagnostic message.
3573+
OOK_Macro,
3574+
};
3575+
35663576
DeclResult ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
35673577
SourceLocation KWLoc, CXXScopeSpec &SS,
35683578
IdentifierInfo *Name, SourceLocation NameLoc,
@@ -3573,7 +3583,7 @@ class Sema final {
35733583
SourceLocation ScopedEnumKWLoc,
35743584
bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
35753585
bool IsTypeSpecifier, bool IsTemplateParamOrArg,
3576-
SkipBodyInfo *SkipBody = nullptr);
3586+
OffsetOfKind OOK, SkipBodyInfo *SkipBody = nullptr);
35773587

35783588
DeclResult ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc,
35793589
unsigned TagSpec, SourceLocation TagLoc,

clang/lib/AST/Interp/ByteCodeExprGen.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -802,7 +802,11 @@ unsigned ByteCodeExprGen<Emitter>::allocateLocalPrimitive(DeclTy &&Src,
802802
PrimType Ty,
803803
bool IsConst,
804804
bool IsExtended) {
805-
Descriptor *D = P.createDescriptor(Src, Ty, IsConst, Src.is<const Expr *>());
805+
// FIXME: There are cases where Src.is<Expr*>() is wrong, e.g.
806+
// (int){12} in C. Consider using Expr::isTemporaryObject() instead
807+
// or isa<MaterializeTemporaryExpr>().
808+
Descriptor *D = P.createDescriptor(Src, Ty, Descriptor::InlineDescMD, IsConst,
809+
Src.is<const Expr *>());
806810
Scope::Local Local = this->createLocal(D);
807811
if (auto *VD = dyn_cast_or_null<ValueDecl>(Src.dyn_cast<const Decl *>()))
808812
Locals.insert({VD, Local});
@@ -831,7 +835,8 @@ ByteCodeExprGen<Emitter>::allocateLocal(DeclTy &&Src, bool IsExtended) {
831835
}
832836

833837
Descriptor *D = P.createDescriptor(
834-
Src, Ty.getTypePtr(), Ty.isConstQualified(), IsTemporary, false, Init);
838+
Src, Ty.getTypePtr(), Descriptor::InlineDescMD, Ty.isConstQualified(),
839+
IsTemporary, /*IsMutable=*/false, Init);
835840
if (!D)
836841
return {};
837842

clang/lib/AST/Interp/ByteCodeStmtGen.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -402,24 +402,26 @@ bool ByteCodeStmtGen<Emitter>::visitVarDecl(const VarDecl *VD) {
402402
if (std::optional<PrimType> T = this->classify(VD->getType())) {
403403
const Expr *Init = VD->getInit();
404404

405-
if (!Init)
406-
return false;
407-
408405
unsigned Offset =
409406
this->allocateLocalPrimitive(VD, *T, VD->getType().isConstQualified());
410407
// Compile the initializer in its own scope.
411-
{
408+
if (Init) {
412409
ExprScope<Emitter> Scope(this);
413410
if (!this->visit(Init))
414411
return false;
412+
413+
return this->emitSetLocal(*T, Offset, VD);
415414
}
416-
// Set the value.
417-
return this->emitSetLocal(*T, Offset, VD);
415+
return true;
418416
}
419417

420418
// Composite types - allocate storage and initialize it.
421-
if (std::optional<unsigned> Offset = this->allocateLocal(VD))
419+
if (std::optional<unsigned> Offset = this->allocateLocal(VD)) {
420+
if (!VD->getInit())
421+
return true;
422+
422423
return this->visitLocalInitializer(VD->getInit(), *Offset);
424+
}
423425

424426
return this->bail(VD);
425427
}

clang/lib/AST/Interp/Context.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ unsigned Context::getCharBit() const {
125125

126126
bool Context::Run(State &Parent, Function *Func, APValue &Result) {
127127
InterpState State(Parent, *P, Stk, *this);
128-
State.Current = new InterpFrame(State, Func, nullptr, {}, {});
128+
State.Current = new InterpFrame(State, Func, /*Caller=*/nullptr, {});
129129
if (Interpret(State, Result))
130130
return true;
131131
Stk.clear();

clang/lib/AST/Interp/Descriptor.cpp

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -191,19 +191,22 @@ static BlockMoveFn getMoveArrayPrim(PrimType Type) {
191191
COMPOSITE_TYPE_SWITCH(Type, return moveArrayTy<T>, return nullptr);
192192
}
193193

194-
Descriptor::Descriptor(const DeclTy &D, PrimType Type, bool IsConst,
195-
bool IsTemporary, bool IsMutable)
196-
: Source(D), ElemSize(primSize(Type)), Size(ElemSize), AllocSize(Size),
197-
IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary),
198-
CtorFn(getCtorPrim(Type)), DtorFn(getDtorPrim(Type)),
199-
MoveFn(getMovePrim(Type)) {
194+
Descriptor::Descriptor(const DeclTy &D, PrimType Type, MetadataSize MD,
195+
bool IsConst, bool IsTemporary, bool IsMutable)
196+
: Source(D), ElemSize(primSize(Type)), Size(ElemSize),
197+
MDSize(MD.value_or(0)), AllocSize(align(Size + MDSize)), IsConst(IsConst),
198+
IsMutable(IsMutable), IsTemporary(IsTemporary), CtorFn(getCtorPrim(Type)),
199+
DtorFn(getDtorPrim(Type)), MoveFn(getMovePrim(Type)) {
200+
assert(AllocSize >= Size);
200201
assert(Source && "Missing source");
201202
}
202203

203-
Descriptor::Descriptor(const DeclTy &D, PrimType Type, size_t NumElems,
204-
bool IsConst, bool IsTemporary, bool IsMutable)
204+
Descriptor::Descriptor(const DeclTy &D, PrimType Type, MetadataSize MD,
205+
size_t NumElems, bool IsConst, bool IsTemporary,
206+
bool IsMutable)
205207
: Source(D), ElemSize(primSize(Type)), Size(ElemSize * NumElems),
206-
AllocSize(align(Size) + sizeof(InitMap *)), IsConst(IsConst),
208+
MDSize(MD.value_or(0)),
209+
AllocSize(align(Size) + sizeof(InitMap *) + MDSize), IsConst(IsConst),
207210
IsMutable(IsMutable), IsTemporary(IsTemporary), IsArray(true),
208211
CtorFn(getCtorArrayPrim(Type)), DtorFn(getDtorArrayPrim(Type)),
209212
MoveFn(getMoveArrayPrim(Type)) {
@@ -212,39 +215,42 @@ Descriptor::Descriptor(const DeclTy &D, PrimType Type, size_t NumElems,
212215

213216
Descriptor::Descriptor(const DeclTy &D, PrimType Type, bool IsTemporary,
214217
UnknownSize)
215-
: Source(D), ElemSize(primSize(Type)), Size(UnknownSizeMark),
218+
: Source(D), ElemSize(primSize(Type)), Size(UnknownSizeMark), MDSize(0),
216219
AllocSize(alignof(void *)), IsConst(true), IsMutable(false),
217220
IsTemporary(IsTemporary), IsArray(true), CtorFn(getCtorArrayPrim(Type)),
218221
DtorFn(getDtorArrayPrim(Type)), MoveFn(getMoveArrayPrim(Type)) {
219222
assert(Source && "Missing source");
220223
}
221224

222-
Descriptor::Descriptor(const DeclTy &D, Descriptor *Elem, unsigned NumElems,
223-
bool IsConst, bool IsTemporary, bool IsMutable)
225+
Descriptor::Descriptor(const DeclTy &D, Descriptor *Elem, MetadataSize MD,
226+
unsigned NumElems, bool IsConst, bool IsTemporary,
227+
bool IsMutable)
224228
: Source(D), ElemSize(Elem->getAllocSize() + sizeof(InlineDescriptor)),
225-
Size(ElemSize * NumElems),
226-
AllocSize(std::max<size_t>(alignof(void *), Size)), ElemDesc(Elem),
227-
IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary),
228-
IsArray(true), CtorFn(ctorArrayDesc), DtorFn(dtorArrayDesc),
229-
MoveFn(moveArrayDesc) {
229+
Size(ElemSize * NumElems), MDSize(MD.value_or(0)),
230+
AllocSize(std::max<size_t>(alignof(void *), Size) + MDSize),
231+
ElemDesc(Elem), IsConst(IsConst), IsMutable(IsMutable),
232+
IsTemporary(IsTemporary), IsArray(true), CtorFn(ctorArrayDesc),
233+
DtorFn(dtorArrayDesc), MoveFn(moveArrayDesc) {
230234
assert(Source && "Missing source");
231235
}
232236

233237
Descriptor::Descriptor(const DeclTy &D, Descriptor *Elem, bool IsTemporary,
234238
UnknownSize)
235239
: Source(D), ElemSize(Elem->getAllocSize() + sizeof(InlineDescriptor)),
236-
Size(UnknownSizeMark), AllocSize(alignof(void *)), ElemDesc(Elem),
237-
IsConst(true), IsMutable(false), IsTemporary(IsTemporary), IsArray(true),
238-
CtorFn(ctorArrayDesc), DtorFn(dtorArrayDesc), MoveFn(moveArrayDesc) {
240+
Size(UnknownSizeMark), MDSize(0), AllocSize(alignof(void *)),
241+
ElemDesc(Elem), IsConst(true), IsMutable(false), IsTemporary(IsTemporary),
242+
IsArray(true), CtorFn(ctorArrayDesc), DtorFn(dtorArrayDesc),
243+
MoveFn(moveArrayDesc) {
239244
assert(Source && "Missing source");
240245
}
241246

242-
Descriptor::Descriptor(const DeclTy &D, Record *R, bool IsConst,
243-
bool IsTemporary, bool IsMutable)
247+
Descriptor::Descriptor(const DeclTy &D, Record *R, MetadataSize MD,
248+
bool IsConst, bool IsTemporary, bool IsMutable)
244249
: Source(D), ElemSize(std::max<size_t>(alignof(void *), R->getFullSize())),
245-
Size(ElemSize), AllocSize(Size), ElemRecord(R), IsConst(IsConst),
246-
IsMutable(IsMutable), IsTemporary(IsTemporary), CtorFn(ctorRecord),
247-
DtorFn(dtorRecord), MoveFn(moveRecord) {
250+
Size(ElemSize), MDSize(MD.value_or(0)), AllocSize(Size + MDSize),
251+
ElemRecord(R), IsConst(IsConst), IsMutable(IsMutable),
252+
IsTemporary(IsTemporary), CtorFn(ctorRecord), DtorFn(dtorRecord),
253+
MoveFn(moveRecord) {
248254
assert(Source && "Missing source");
249255
}
250256

0 commit comments

Comments
 (0)