Skip to content

Commit 9d7e79d

Browse files
committed
forbid mixed enums
1 parent f009991 commit 9d7e79d

File tree

4 files changed

+84
-7
lines changed

4 files changed

+84
-7
lines changed

clang/lib/Sema/SemaChecking.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14645,13 +14645,27 @@ bool Sema::BuiltinVectorToScalarMath(CallExpr *TheCall) {
1464514645
return false;
1464614646
}
1464714647

14648+
static bool checkBuiltinVectorMathMixedEnums(Sema &S, Expr *LHS, Expr *RHS,
14649+
SourceLocation Loc) {
14650+
QualType L = LHS->getEnumCoercedType(S.Context),
14651+
R = RHS->getEnumCoercedType(S.Context);
14652+
if (L->isUnscopedEnumerationType() && R->isUnscopedEnumerationType() &&
14653+
!S.Context.hasSameUnqualifiedType(L, R)) {
14654+
return S.Diag(Loc, diag::err_conv_mixed_enum_types_cxx26)
14655+
<< LHS->getSourceRange() << RHS->getSourceRange()
14656+
<< /*Arithmetic Between*/ 0 << L << R;
14657+
}
14658+
return false;
14659+
}
14660+
1464814661
std::optional<QualType> Sema::BuiltinVectorMath(CallExpr *TheCall,
1464914662
bool FPOnly) {
1465014663
if (checkArgCount(TheCall, 2))
1465114664
return std::nullopt;
1465214665

14653-
checkEnumArithmeticConversions(TheCall->getArg(0), TheCall->getArg(1),
14654-
TheCall->getExprLoc(), ACK_Comparison);
14666+
if (checkBuiltinVectorMathMixedEnums(
14667+
*this, TheCall->getArg(0), TheCall->getArg(1), TheCall->getExprLoc()))
14668+
return std::nullopt;
1465514669

1465614670
Expr *Args[2];
1465714671
for (int I = 0; I < 2; ++I) {
@@ -14689,6 +14703,13 @@ bool Sema::BuiltinElementwiseTernaryMath(CallExpr *TheCall,
1468914703
if (checkArgCount(TheCall, 3))
1469014704
return true;
1469114705

14706+
SourceLocation Loc = TheCall->getExprLoc();
14707+
if (checkBuiltinVectorMathMixedEnums(*this, TheCall->getArg(0),
14708+
TheCall->getArg(1), Loc) ||
14709+
checkBuiltinVectorMathMixedEnums(*this, TheCall->getArg(1),
14710+
TheCall->getArg(2), Loc))
14711+
return true;
14712+
1469214713
Expr *Args[3];
1469314714
for (int I = 0; I < 3; ++I) {
1469414715
ExprResult Converted =

clang/test/CodeGen/builtins-elementwise-math.c

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,18 @@ __attribute__((address_space(1))) int int_as_one;
1414
typedef int bar;
1515
bar b;
1616

17+
struct StructWithBitfield {
18+
int i : 5;
19+
short s : 3;
20+
char c: 2;
21+
long long int lli : 3;
22+
};
23+
1724
void test_builtin_elementwise_abs(float f1, float f2, double d1, double d2,
1825
float4 vf1, float4 vf2, si8 vi1, si8 vi2,
1926
long long int i1, long long int i2, short si,
20-
_BitInt(31) bi1, _BitInt(31) bi2) {
27+
_BitInt(31) bi1, _BitInt(31) bi2, int i,
28+
char ci) {
2129
// CHECK-LABEL: define void @test_builtin_elementwise_abs(
2230
// CHECK: [[F1:%.+]] = load float, ptr %f1.addr, align 4
2331
// CHECK-NEXT: call float @llvm.fabs.f32(float [[F1]])
@@ -64,6 +72,35 @@ void test_builtin_elementwise_abs(float f1, float f2, double d1, double d2,
6472
// CHECK: [[SI:%.+]] = load i16, ptr %si.addr, align 2
6573
// CHECK-NEXT: [[RES:%.+]] = call i16 @llvm.abs.i16(i16 [[SI]], i1 false)
6674
si = __builtin_elementwise_abs(si);
75+
76+
struct StructWithBitfield t;
77+
78+
// CHECK: [[BFLOAD:%.+]] = load i16, ptr %t, align 8
79+
// CHECK-NEXT: [[BFSHL:%.+]] = shl i16 [[BFLOAD]], 11
80+
// CHECK-NEXT: [[BFASHR:%.+]] = ashr i16 [[BFSHL]], 11
81+
// CHECK-NEXT: [[BFCAST:%.+]] = sext i16 [[BFASHR]] to i32
82+
// CHECK-NEXT: [[RES:%.+]] = call i32 @llvm.abs.i32(i32 [[BFCAST]], i1 false)
83+
i = __builtin_elementwise_abs(t.i);
84+
85+
// CHECK: [[BFLOAD:%.+]] = load i16, ptr %t, align 8
86+
// CHECK-NEXT: [[BFSHL:%.+]] = shl i16 [[BFLOAD]], 8
87+
// CHECK-NEXT: [[BFASHR:%.+]] = ashr i16 [[BFSHL]], 13
88+
// CHECK-NEXT: [[RES:%.+]] = call i16 @llvm.abs.i16(i16 [[BFASHR]], i1 false)
89+
si = __builtin_elementwise_abs(t.s);
90+
91+
// CHECK: [[BFLOAD:%.+]] = load i16, ptr %t, align 8
92+
// CHECK-NEXT: [[BFSHL:%.+]] = shl i16 [[BFLOAD]], 6
93+
// CHECK-NEXT: [[BFASHR:%.+]] = ashr i16 [[BFSHL]], 14
94+
// CHECK-NEXT: [[BFCAST:%.+]] = trunc i16 [[BFASHR]] to i8
95+
// CHECK-NEXT: [[RES:%.+]] = call i8 @llvm.abs.i8(i8 [[BFCAST]], i1 false)
96+
ci = __builtin_elementwise_abs(t.c);
97+
98+
// CHECK: [[BFLOAD:%.+]] = load i16, ptr %t, align 8
99+
// CHECK-NEXT: [[BFSHL:%.+]] = shl i16 [[BFLOAD]], 3
100+
// CHECK-NEXT: [[BFASHR:%.+]] = ashr i16 [[BFSHL]], 13
101+
// CHECK-NEXT: [[BFCAST:%.+]] = sext i16 [[BFASHR]] to i64
102+
// CHECK-NEXT: [[RES:%.+]] = call i64 @llvm.abs.i64(i64 [[BFCAST]], i1 false)
103+
i1 = __builtin_elementwise_abs(t.lli);
67104
}
68105

69106
void test_builtin_elementwise_add_sat(float f1, float f2, double d1, double d2,

clang/test/Sema/builtins-elementwise-math.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,12 @@ void test_builtin_elementwise_add_sat(int i, short s, double d, float4 v, int3 i
7575
two };
7676
i = __builtin_elementwise_add_sat(one, two);
7777

78+
i = __builtin_elementwise_add_sat(one, d);
79+
// expected-error@-1 {{arguments are of different types ('int' vs 'double')}}
80+
7881
enum f { three };
7982
enum f x = __builtin_elementwise_add_sat(one, three);
80-
// expected-warning@-1 {{comparison of different enumeration types ('enum e' and 'enum f')}}
83+
// expected-error@-1 {{invalid arithmetic between different enumeration types ('enum e' and 'enum f')}}
8184

8285
_BitInt(32) ext; // expected-warning {{'_BitInt' in C17 and earlier is a Clang extension}}
8386
ext = __builtin_elementwise_add_sat(ext, ext);
@@ -135,9 +138,12 @@ void test_builtin_elementwise_sub_sat(int i, short s, double d, float4 v, int3 i
135138
two };
136139
i = __builtin_elementwise_sub_sat(one, two);
137140

141+
i = __builtin_elementwise_sub_sat(one, d);
142+
// expected-error@-1 {{arguments are of different types ('int' vs 'double')}}
143+
138144
enum f { three };
139145
enum f x = __builtin_elementwise_sub_sat(one, three);
140-
// expected-warning@-1 {{comparison of different enumeration types ('enum e' and 'enum f')}}
146+
// expected-error@-1 {{invalid arithmetic between different enumeration types ('enum e' and 'enum f')}}
141147

142148
_BitInt(32) ext; // expected-warning {{'_BitInt' in C17 and earlier is a Clang extension}}
143149
ext = __builtin_elementwise_sub_sat(ext, ext);
@@ -192,9 +198,12 @@ void test_builtin_elementwise_max(int i, short s, double d, float4 v, int3 iv, u
192198
two };
193199
i = __builtin_elementwise_max(one, two);
194200

201+
i = __builtin_elementwise_max(one, d);
202+
// expected-error@-1 {{arguments are of different types ('int' vs 'double')}}
203+
195204
enum f { three };
196205
enum f x = __builtin_elementwise_max(one, three);
197-
// expected-warning@-1 {{comparison of different enumeration types ('enum e' and 'enum f')}}
206+
// expected-error@-1 {{invalid arithmetic between different enumeration types ('enum e' and 'enum f')}}
198207

199208
_BitInt(32) ext; // expected-warning {{'_BitInt' in C17 and earlier is a Clang extension}}
200209
ext = __builtin_elementwise_max(ext, ext);
@@ -249,9 +258,12 @@ void test_builtin_elementwise_min(int i, short s, double d, float4 v, int3 iv, u
249258
two };
250259
i = __builtin_elementwise_min(one, two);
251260

261+
i = __builtin_elementwise_min(one, d);
262+
// expected-error@-1 {{arguments are of different types ('int' vs 'double')}}
263+
252264
enum f { three };
253265
enum f x = __builtin_elementwise_min(one, three);
254-
// expected-warning@-1 {{comparison of different enumeration types ('enum e' and 'enum f')}}
266+
// expected-error@-1 {{invalid arithmetic between different enumeration types ('enum e' and 'enum f')}}
255267

256268
_BitInt(32) ext; // expected-warning {{'_BitInt' in C17 and earlier is a Clang extension}}
257269
ext = __builtin_elementwise_min(ext, ext);

clang/test/SemaHLSL/BuiltIns/mad-errors.hlsl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,10 @@ float builtin_mad_int_to_float_promotion(float p0, int p1) {
8484
return __builtin_hlsl_mad(p0, p0, p1);
8585
// expected-error@-1 {{3rd argument must be a floating point type (was 'int')}}
8686
}
87+
88+
int builtin_mad_mixed_enums() {
89+
enum e { one, two };
90+
enum f { three };
91+
return __builtin_hlsl_mad(one, two, three);
92+
// expected-error@-1 {{invalid arithmetic between different enumeration types ('e' and 'f')}}
93+
}

0 commit comments

Comments
 (0)