Skip to content

Commit 373ccc9

Browse files
adriwebcodex
andcommitted
clang/AST/Type: try to fix sizeof static assertion on Windows.
Mess with how functions tiflags attribute is stored... Co-Authored-By: Codex CLI <codex@openai.com>
1 parent 98df88a commit 373ccc9

6 files changed

Lines changed: 106 additions & 9 deletions

File tree

clang/include/clang/AST/Type.h

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1942,7 +1942,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
19421942
/// Extra information which affects how the function is called, like
19431943
/// regparm and the calling convention.
19441944
LLVM_PREFERRED_TYPE(CallingConv)
1945-
unsigned ExtInfo : 14;
1945+
unsigned ExtInfo : 13;
19461946

19471947
/// The ref-qualifier associated with a \c FunctionProtoType.
19481948
///
@@ -4395,8 +4395,6 @@ class FunctionType : public Type {
43954395

43964396
// | CC |noreturn|produces|nocallersavedregs|regparm|nocfcheck|cmsenscall|
43974397
// |0 .. 4| 5 | 6 | 7 |8 .. 10| 11 | 12 |
4398-
// |tiflags|
4399-
// | 13 |
44004398
//
44014399
// regparm is either 0 (no regparm attribute) or the regparm value+1.
44024400
enum { CallConvMask = 0x1F };
@@ -4541,10 +4539,12 @@ class FunctionType : public Type {
45414539
LLVM_PREFERRED_TYPE(bool)
45424540
unsigned EffectsHaveConditions : 1;
45434541
unsigned NumFunctionEffects : 4;
4542+
LLVM_PREFERRED_TYPE(bool)
4543+
unsigned TIFlags : 1;
45444544

45454545
FunctionTypeExtraBitfields()
45464546
: NumExceptionType(0), HasArmTypeAttributes(false),
4547-
EffectsHaveConditions(false), NumFunctionEffects(0) {}
4547+
EffectsHaveConditions(false), NumFunctionEffects(0), TIFlags(false) {}
45484548
};
45494549

45504550
/// The AArch64 SME ACLE (Arm C/C++ Language Extensions) define a number
@@ -4597,7 +4597,7 @@ class FunctionType : public Type {
45974597
FunctionType(TypeClass tc, QualType res, QualType Canonical,
45984598
TypeDependence Dependence, ExtInfo Info)
45994599
: Type(tc, Canonical, Dependence), ResultType(res) {
4600-
FunctionTypeBits.ExtInfo = Info.Bits;
4600+
FunctionTypeBits.ExtInfo = Info.Bits & ~ExtInfo::TIFlagsMask;
46014601
}
46024602

46034603
Qualifiers getFastTypeQuals() const {
@@ -4620,7 +4620,7 @@ class FunctionType : public Type {
46204620

46214621
bool getCmseNSCallAttr() const { return getExtInfo().getCmseNSCall(); }
46224622
CallingConv getCallConv() const { return getExtInfo().getCC(); }
4623-
ExtInfo getExtInfo() const { return ExtInfo(FunctionTypeBits.ExtInfo); }
4623+
ExtInfo getExtInfo() const;
46244624

46254625
static_assert((~Qualifiers::FastMask & Qualifiers::CVRMask) == 0,
46264626
"Const, volatile and restrict are assumed to be a subset of "
@@ -4648,17 +4648,20 @@ class FunctionType : public Type {
46484648
/// no information available about its arguments.
46494649
class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
46504650
friend class ASTContext; // ASTContext creates these.
4651+
friend class FunctionType;
4652+
4653+
LLVM_PREFERRED_TYPE(bool)
4654+
unsigned TIFlags : 1;
46514655

46524656
FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info)
46534657
: FunctionType(FunctionNoProto, Result, Canonical,
46544658
Result->getDependence() &
46554659
~(TypeDependence::DependentInstantiation |
46564660
TypeDependence::UnexpandedPack),
4657-
Info) {}
4661+
Info),
4662+
TIFlags(Info.getTIFlags()) {}
46584663

46594664
public:
4660-
// No additional state past what FunctionType provides.
4661-
46624665
bool isSugared() const { return false; }
46634666
QualType desugar() const { return QualType(this, 0); }
46644667

@@ -4984,6 +4987,7 @@ class FunctionProtoType final
49844987
FunctionEffect, EffectConditionExpr> {
49854988
friend class ASTContext; // ASTContext creates these.
49864989
friend TrailingObjects;
4990+
friend class FunctionType;
49874991

49884992
// FunctionProtoType is followed by several trailing objects, some of
49894993
// which optional. They are in order:
@@ -5094,6 +5098,7 @@ class FunctionProtoType final
50945098

50955099
bool requiresFunctionProtoTypeExtraBitfields() const {
50965100
return ExceptionSpec.Type == EST_Dynamic ||
5101+
ExtInfo.getTIFlags() ||
50975102
requiresFunctionProtoTypeArmAttributes() ||
50985103
!FunctionEffects.empty();
50995104
}
@@ -5229,6 +5234,11 @@ class FunctionProtoType final
52295234
->HasArmTypeAttributes;
52305235
}
52315236

5237+
bool hasTIFlags() const {
5238+
return hasExtraBitfields() &&
5239+
getTrailingObjects<FunctionTypeExtraBitfields>()->TIFlags;
5240+
}
5241+
52325242
bool hasExtQualifiers() const {
52335243
return FunctionTypeBits.HasExtQuals;
52345244
}

clang/lib/AST/Type.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3463,6 +3463,18 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const {
34633463
llvm_unreachable("Invalid builtin type.");
34643464
}
34653465

3466+
FunctionType::ExtInfo FunctionType::getExtInfo() const {
3467+
ExtInfo Info(FunctionTypeBits.ExtInfo);
3468+
switch (getTypeClass()) {
3469+
case FunctionNoProto:
3470+
return Info.withTIFlags(cast<FunctionNoProtoType>(this)->TIFlags);
3471+
case FunctionProto:
3472+
return Info.withTIFlags(cast<FunctionProtoType>(this)->hasTIFlags());
3473+
default:
3474+
llvm_unreachable("unexpected function type class");
3475+
}
3476+
}
3477+
34663478
QualType QualType::getNonPackExpansionType() const {
34673479
// We never wrap type sugar around a PackExpansionType.
34683480
if (auto *PET = dyn_cast<PackExpansionType>(getTypePtr()))
@@ -3544,6 +3556,7 @@ FunctionProtoType::FunctionProtoType(QualType result, ArrayRef<QualType> params,
35443556
FunctionTypeBits.HasExtraBitfields = true;
35453557
auto &ExtraBits = *getTrailingObjects<FunctionTypeExtraBitfields>();
35463558
ExtraBits = FunctionTypeExtraBitfields();
3559+
ExtraBits.TIFlags = epi.ExtInfo.getTIFlags();
35473560
} else {
35483561
FunctionTypeBits.HasExtraBitfields = false;
35493562
}

clang/test/AST/z80-tiflags-print.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %clang_cc1 -triple ez80-none-elf -ast-print %s | FileCheck %s
2+
// RUN: %clang_cc1 -triple ez80-none-elf -emit-pch -o %t %s
3+
// RUN: %clang_cc1 -triple ez80-none-elf -include-pch %t -ast-print /dev/null | FileCheck %s
4+
5+
// CHECK: __attribute__((tiflags)) __attribute__((tiflags)) int proto(int);
6+
int __attribute__((tiflags)) proto(int);
7+
8+
// CHECK: __attribute__((tiflags)) __attribute__((tiflags)) int knr();
9+
int __attribute__((tiflags)) knr();
10+
11+
// CHECK: __attribute__((tiflags)) int (*ti_proto)(int) __attribute__((tiflags));
12+
int (__attribute__((tiflags)) *ti_proto)(int);
13+
14+
// CHECK: __attribute__((tiflags)) int (*ti_knr)() __attribute__((tiflags));
15+
int (__attribute__((tiflags)) *ti_knr)();

clang/test/CodeGen/z80-tiflags.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// RUN: %clang_cc1 -triple ez80-none-elf -Wno-strict-prototypes -emit-llvm -o - %s | FileCheck %s
2+
3+
void __attribute__((tiflags)) decl(void);
4+
void __attribute__((tiflags)) def(void) {}
5+
void __attribute__((tiflags)) knr();
6+
7+
void caller(void) {
8+
decl();
9+
def();
10+
void (__attribute__((tiflags)) *pf)(void) = decl;
11+
pf();
12+
}
13+
14+
void call_knr(void) { knr(); }
15+
16+
// CHECK-LABEL: define dso_local cc112 void @def()
17+
// CHECK-LABEL: define dso_local void @caller()
18+
// CHECK: call cc112 void @decl()
19+
// CHECK: call cc112 void @def()
20+
// CHECK: call cc112 void %{{.*}}()
21+
// CHECK: declare cc112 void @decl()
22+
// CHECK-LABEL: define dso_local void @call_knr()
23+
// CHECK: call cc112 void @knr()
24+
// CHECK: declare cc112 void @knr(...)

clang/test/PCH/z80-tiflags.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Test this without PCH.
2+
// RUN: %clang_cc1 -triple ez80-none-elf -include %s -fsyntax-only -verify %s
3+
4+
// Test with PCH.
5+
// RUN: %clang_cc1 -triple ez80-none-elf -emit-pch -o %t %s
6+
// RUN: %clang_cc1 -triple ez80-none-elf -include-pch %t -fsyntax-only -verify %s
7+
8+
#ifndef HEADER
9+
#define HEADER
10+
11+
void __attribute__((tiflags)) from_pch(int);
12+
void (__attribute__((tiflags)) *pf_from_pch)(int);
13+
14+
#else
15+
16+
void from_pch(int); // expected-error {{conflicting types for 'from_pch'}}
17+
// expected-note@-6 {{previous declaration is here}}
18+
void (*pf_plain)(int) = from_pch; // expected-error {{incompatible function pointer types initializing 'void (*)(int)' with an expression of type 'void (int) __attribute__((tiflags))'}}
19+
void (__attribute__((tiflags)) *pf_ok)(int) = from_pch;
20+
21+
#endif

clang/test/Sema/z80-tiflags.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %clang_cc1 %s -fsyntax-only -triple ez80-none-elf -verify
2+
3+
void __attribute__((tiflags)) redecl(int); // expected-note {{previous declaration is here}}
4+
void redecl(int); // expected-error {{conflicting types for 'redecl'}}
5+
6+
void __attribute__((tiflags)) only_ti(int);
7+
8+
void (__attribute__((cdecl)) *p1)(int) = only_ti; // expected-error {{incompatible function pointer types initializing 'void (*)(int) __attribute__((cdecl))' with an expression of type 'void (int) __attribute__((tiflags))'}}
9+
void (*p2)(int) = only_ti; // expected-error {{incompatible function pointer types initializing 'void (*)(int)' with an expression of type 'void (int) __attribute__((tiflags))'}}
10+
void (__attribute__((tiflags)) *p3)(int) = only_ti;
11+
12+
void (__attribute__((tiflags)) *np1)() =
13+
(void (__attribute__((tiflags)) *)())0;
14+
void (*np2)() = (void (__attribute__((tiflags)) *)())0; // expected-error {{incompatible function pointer types initializing 'void (*)()' with an expression of type 'void (*)() __attribute__((tiflags))'}}

0 commit comments

Comments
 (0)