Skip to content

Commit 3aebb27

Browse files
committed
C++: Add support for C23 _BitInts
1 parent 4812cdd commit 3aebb27

2 files changed

Lines changed: 87 additions & 40 deletions

File tree

‎cpp/ql/lib/semmle/code/cpp/Type.qll‎

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,8 @@ private predicate isIntegralType(@builtintype type, int kind) {
398398
kind = 44
399399
or
400400
kind = 51
401+
or
402+
67 <= kind and kind <= 69
401403
)
402404
}
403405

@@ -484,6 +486,12 @@ private predicate integralTypeMapping(int original, int canonical, int unsigned,
484486
original = 44 and canonical = 44 and unsigned = -1 and signed = -1 // char32_t
485487
or
486488
original = 51 and canonical = 51 and unsigned = -1 and signed = -1 // char8_t
489+
or
490+
original = 67 and canonical = 67 and unsigned = 68 and signed = 69 // _BitInt(N)
491+
or
492+
original = 68 and canonical = 68 and unsigned = 68 and signed = 69 // unsigned _BitInt(N)
493+
or
494+
original = 69 and canonical = 67 and unsigned = 68 and signed = 69 // signed _BitInt(N)
487495
}
488496

489497
/**
@@ -517,7 +525,8 @@ class IntegralType extends ArithmeticType, IntegralOrEnumType {
517525
builtintypes(underlyingElement(this), _, 13, _, _, _) or
518526
builtintypes(underlyingElement(this), _, 16, _, _, _) or
519527
builtintypes(underlyingElement(this), _, 19, _, _, _) or
520-
builtintypes(underlyingElement(this), _, 37, _, _, _)
528+
builtintypes(underlyingElement(this), _, 37, _, _, _) or
529+
builtintypes(underlyingElement(this), _, 69, _, _, _)
521530
}
522531

523532
/** Holds if this integral type is explicitly unsigned. */
@@ -527,7 +536,8 @@ class IntegralType extends ArithmeticType, IntegralOrEnumType {
527536
builtintypes(underlyingElement(this), _, 12, _, _, _) or
528537
builtintypes(underlyingElement(this), _, 15, _, _, _) or
529538
builtintypes(underlyingElement(this), _, 18, _, _, _) or
530-
builtintypes(underlyingElement(this), _, 36, _, _, _)
539+
builtintypes(underlyingElement(this), _, 36, _, _, _) or
540+
builtintypes(underlyingElement(this), _, 68, _, _, _)
531541
}
532542

533543
/** Holds if this integral type is implicitly signed. */
@@ -537,7 +547,8 @@ class IntegralType extends ArithmeticType, IntegralOrEnumType {
537547
builtintypes(underlyingElement(this), _, 11, _, -1, _) or
538548
builtintypes(underlyingElement(this), _, 14, _, -1, _) or
539549
builtintypes(underlyingElement(this), _, 17, _, -1, _) or
540-
builtintypes(underlyingElement(this), _, 35, _, -1, _)
550+
builtintypes(underlyingElement(this), _, 35, _, -1, _) or
551+
builtintypes(underlyingElement(this), _, 67, _, -1, _)
541552
}
542553

543554
/**
@@ -547,7 +558,14 @@ class IntegralType extends ArithmeticType, IntegralOrEnumType {
547558
IntegralType getUnsigned() {
548559
exists(int unsignedKind |
549560
integralTypeMapping(kind, _, unsignedKind, _) and
550-
builtintypes(unresolveElement(result), _, unsignedKind, _, _, _)
561+
builtintypes(unresolveElement(result), _, unsignedKind, _, _, _) and
562+
(
563+
not kind in [67, 68, 69]
564+
or
565+
exists(int bitWidth | bit_precise_int_types(underlyingElement(this), bitWidth) |
566+
bit_precise_int_types(unresolveElement(result), bitWidth)
567+
)
568+
)
551569
)
552570
}
553571

@@ -562,7 +580,14 @@ class IntegralType extends ArithmeticType, IntegralOrEnumType {
562580
IntegralType getCanonicalArithmeticType() {
563581
exists(int canonicalKind |
564582
integralTypeMapping(kind, canonicalKind, _, _) and
565-
builtintypes(unresolveElement(result), _, canonicalKind, _, _, _)
583+
builtintypes(unresolveElement(result), _, canonicalKind, _, _, _) and
584+
(
585+
not kind in [67, 68, 69]
586+
or
587+
exists(int bitWidth | bit_precise_int_types(underlyingElement(this), bitWidth) |
588+
bit_precise_int_types(unresolveElement(result), bitWidth)
589+
)
590+
)
566591
)
567592
}
568593
}
@@ -1045,6 +1070,18 @@ class Char32Type extends IntegralType {
10451070
override string getAPrimaryQlClass() { result = "Char32Type" }
10461071
}
10471072

1073+
/**
1074+
* A C23 bit-precise integer type `_BitInt(N)`.
1075+
*/
1076+
class BitPreciseIntegerType extends IntegralType {
1077+
BitPreciseIntegerType() { builtintypes(underlyingElement(this), _, [67, 68, 69], _, _, _) }
1078+
1079+
/** Get the bit-with of the bit-precise integer. */
1080+
int getBitWidth() { bit_precise_int_types(underlyingElement(this), result) }
1081+
1082+
override string getAPrimaryQlClass() { result = "BitPreciseIntType" }
1083+
}
1084+
10481085
/**
10491086
* The (primitive) type of the C++11 `nullptr` constant. It is a
10501087
* distinct type, denoted by `decltype(nullptr)`, that is not itself a pointer

‎cpp/ql/lib/semmlecode.cpp.dbscheme‎

Lines changed: 45 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -660,46 +660,49 @@ case @builtintype.kind of
660660
| 24 = @float
661661
| 25 = @double
662662
| 26 = @long_double
663-
| 27 = @complex_float // C99-specific _Complex float
664-
| 28 = @complex_double // C99-specific _Complex double
665-
| 29 = @complex_long_double // C99-specific _Complex long double
666-
| 30 = @imaginary_float // C99-specific _Imaginary float
667-
| 31 = @imaginary_double // C99-specific _Imaginary double
668-
| 32 = @imaginary_long_double // C99-specific _Imaginary long double
669-
| 33 = @wchar_t // Microsoft-specific
670-
| 34 = @decltype_nullptr // C++11
671-
| 35 = @int128 // __int128
672-
| 36 = @unsigned_int128 // unsigned __int128
673-
| 37 = @signed_int128 // signed __int128
674-
| 38 = @float128 // __float128
675-
| 39 = @complex_float128 // _Complex __float128
663+
| 27 = @complex_float // C99-specific _Complex float
664+
| 28 = @complex_double // C99-specific _Complex double
665+
| 29 = @complex_long_double // C99-specific _Complex long double
666+
| 30 = @imaginary_float // C99-specific _Imaginary float
667+
| 31 = @imaginary_double // C99-specific _Imaginary double
668+
| 32 = @imaginary_long_double // C99-specific _Imaginary long double
669+
| 33 = @wchar_t // Microsoft-specific
670+
| 34 = @decltype_nullptr // C++11
671+
| 35 = @int128 // __int128
672+
| 36 = @unsigned_int128 // unsigned __int128
673+
| 37 = @signed_int128 // signed __int128
674+
| 38 = @float128 // __float128
675+
| 39 = @complex_float128 // _Complex __float128
676676
// ... 40 _Decimal32
677677
// ... 41 _Decimal64
678678
// ... 42 _Decimal128
679679
| 43 = @char16_t
680680
| 44 = @char32_t
681-
| 45 = @std_float32 // _Float32
682-
| 46 = @float32x // _Float32x
683-
| 47 = @std_float64 // _Float64
684-
| 48 = @float64x // _Float64x
685-
| 49 = @std_float128 // _Float128
681+
| 45 = @std_float32 // _Float32
682+
| 46 = @float32x // _Float32x
683+
| 47 = @std_float64 // _Float64
684+
| 48 = @float64x // _Float64x
685+
| 49 = @std_float128 // _Float128
686686
// ... 50 _Float128x
687687
| 51 = @char8_t
688-
| 52 = @float16 // _Float16
689-
| 53 = @complex_float16 // _Complex _Float16
690-
| 54 = @fp16 // __fp16
691-
| 55 = @std_bfloat16 // __bf16
692-
| 56 = @std_float16 // std::float16_t
693-
| 57 = @complex_std_float32 // _Complex _Float32
694-
| 58 = @complex_float32x // _Complex _Float32x
695-
| 59 = @complex_std_float64 // _Complex _Float64
696-
| 60 = @complex_float64x // _Complex _Float64x
697-
| 61 = @complex_std_float128 // _Complex _Float128
698-
| 62 = @mfp8 // __mfp8
699-
| 63 = @scalable_vector_count // __SVCount_t
700-
| 64 = @complex_fp16 // _Complex __fp16
701-
| 65 = @complex_std_bfloat16 // _Complex __bf16
702-
| 66 = @complex_std_float16 // _Complex std::float16_t
688+
| 52 = @float16 // _Float16
689+
| 53 = @complex_float16 // _Complex _Float16
690+
| 54 = @fp16 // __fp16
691+
| 55 = @std_bfloat16 // __bf16
692+
| 56 = @std_float16 // std::float16_t
693+
| 57 = @complex_std_float32 // _Complex _Float32
694+
| 58 = @complex_float32x // _Complex _Float32x
695+
| 59 = @complex_std_float64 // _Complex _Float64
696+
| 60 = @complex_float64x // _Complex _Float64x
697+
| 61 = @complex_std_float128 // _Complex _Float128
698+
| 62 = @mfp8 // __mfp8
699+
| 63 = @scalable_vector_count // __SVCount_t
700+
| 64 = @complex_fp16 // _Complex __fp16
701+
| 65 = @complex_std_bfloat16 // _Complex __bf16
702+
| 66 = @complex_std_float16 // _Complex std::float16_t
703+
| 67 = @bit_precise_int // _BitInt(N)
704+
| 68 = @unsigned_bit_precise_int // unsigned _BitInt(N)
705+
| 69 = @signed_bit_precise_int // signed _BitInt(N)
703706
;
704707

705708
builtintypes(
@@ -711,6 +714,11 @@ builtintypes(
711714
int alignment: int ref
712715
);
713716

717+
bit_precise_int_types(
718+
unique int id: @builtintype ref,
719+
int bit_width: int ref
720+
)
721+
714722
/**
715723
* Derived types are types that are directly derived from existing types and
716724
* point to, refer to, transform type data to return a new type.
@@ -736,9 +744,11 @@ derivedtypes(
736744
int type_id: @type ref
737745
);
738746

739-
pointerishsize(unique int id: @derivedtype ref,
747+
pointerishsize(
748+
unique int id: @derivedtype ref,
740749
int size: int ref,
741-
int alignment: int ref);
750+
int alignment: int ref
751+
);
742752

743753
arraysizes(
744754
unique int id: @derivedtype ref,

0 commit comments

Comments
 (0)