Skip to content

Commit bca24f2

Browse files
committed
add failure tests and reference tests, and adjust checks according to conversation
1 parent 1e9895c commit bca24f2

File tree

7 files changed

+142
-12
lines changed

7 files changed

+142
-12
lines changed

clang/lib/AST/ExprConstant.cpp

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13982,22 +13982,15 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
1398213982

1398313983
return Success(Val.reverseBits(), E);
1398413984
}
13985-
case Builtin::BI__builtin_bswapg: {
13986-
APSInt Val;
13987-
if (!EvaluateInteger(E->getArg(0), Val, Info))
13988-
return false;
13989-
if (Val.getBitWidth() == 8)
13990-
return Success(Val, E);
13991-
13992-
return Success(Val.byteSwap(), E);
13993-
}
13994-
13985+
case Builtin::BI__builtin_bswapg:
1399513986
case Builtin::BI__builtin_bswap16:
1399613987
case Builtin::BI__builtin_bswap32:
1399713988
case Builtin::BI__builtin_bswap64: {
1399813989
APSInt Val;
1399913990
if (!EvaluateInteger(E->getArg(0), Val, Info))
1400013991
return false;
13992+
if (Val.getBitWidth() == 8)
13993+
return Success(Val, E);
1400113994

1400213995
return Success(Val.byteSwap(), E);
1400313996
}

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3626,6 +3626,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
36263626
Value *ArgValue = EmitScalarExpr(E->getArg(0));
36273627
llvm::IntegerType *IntTy = cast<llvm::IntegerType>(ArgValue->getType());
36283628
assert(IntTy && "LLVM's __builtin_bswapg only supports integer variants");
3629+
assert(((IntTy->getBitWidth() % 16 == 0 && IntTy->getBitWidth() != 0) || IntTy->getBitWidth() == 8) &&
3630+
"LLVM's __builtin_bswapg only supports integer variants that has a multiple of 16 bits as well as a single byte");
36293631
if (IntTy->getBitWidth() == 8)
36303632
return RValue::get(ArgValue);
36313633
return RValue::get(

clang/lib/Sema/SemaChecking.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2218,7 +2218,7 @@ static bool BuiltinBswapg(Sema &S, CallExpr *TheCall) {
22182218

22192219
if (!ArgTy->isIntegerType()) {
22202220
S.Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type)
2221-
<< 1 << /* scalar */ 1 << /* unsigned integer ty */ 1 << /* no fp */ 0
2221+
<< 1 << /*scalar=*/ 1 << /*unsigned integer=*/ 1 << /*floating point=*/ 0
22222222
<< ArgTy;
22232223
return true;
22242224
}

clang/test/AST/ByteCode/builtin-functions.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -828,6 +828,25 @@ namespace bswap {
828828
int h7 = __builtin_bswapg(0x1234) == 0x3412 ? 1 : f();
829829
int h8 = __builtin_bswapg(0x00001234) == 0x34120000 ? 1 : f();
830830
int h9 = __builtin_bswapg(0x0000000000001234) == 0x3412000000000000 ? 1 : f();
831+
832+
constexpr const int const_expr = 0x1234;
833+
834+
void test_constexpr_reference() {
835+
const int expr = 0x1234;
836+
const int& ref = expr; // #declare
837+
838+
constexpr const int& const_ref = const_expr;
839+
840+
constexpr auto result2 = __builtin_bswapg(ref);
841+
//expected-error@-1 {{constexpr variable 'result2' must be initialized by a constant expression}}
842+
//expected-note@-2 {{initializer of 'ref' is not a constant expression}}
843+
//expected-note@#declare {{declared here}}
844+
//ref-error@-4 {{constexpr variable 'result2' must be initialized by a constant expression}}
845+
//ref-note@-5 {{initializer of 'ref' is not a constant expression}}
846+
//ref-note@#declare {{declared here}}
847+
848+
constexpr auto result3 = __builtin_bswapg(const_ref);
849+
}
831850
}
832851

833852
#define CFSTR __builtin___CFStringMakeConstantString

clang/test/CodeGenCXX/builtins.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,40 @@ int structured_binding_size() {
8383
return __builtin_structured_binding_size(S2);
8484
// CHECK: ret i32 2
8585
}
86+
87+
void test_int_reference(int& a) {
88+
__builtin_bswapg(a);
89+
}
90+
// CHECK-LABEL: @_Z18test_int_referenceRi
91+
// CHECK: store ptr %a, ptr
92+
// CHECK: load ptr, ptr
93+
// CHECK: load i32, ptr
94+
// CHECK: call i32 @llvm.bswap.i32
95+
96+
void test_long_reference(long& a) {
97+
__builtin_bswapg(a);
98+
}
99+
// CHECK-LABEL: @_Z19test_long_referenceRl
100+
// CHECK: store ptr %a, ptr
101+
// CHECK: load ptr, ptr
102+
// CHECK: load i64, ptr
103+
// CHECK: call i64 @llvm.bswap.i64
104+
105+
// 2. 不同大小的引用测试
106+
void test_short_reference(short& a) {
107+
__builtin_bswapg(a);
108+
}
109+
// CHECK-LABEL: @_Z20test_short_referenceRs
110+
// CHECK: store ptr %a, ptr
111+
// CHECK: load ptr, ptr
112+
// CHECK: load i16, ptr
113+
// CHECK: call i16 @llvm.bswap.i16
114+
115+
void test_char_reference(char& a) {
116+
__builtin_bswapg(a);
117+
}
118+
// CHECK-LABEL: @_Z19test_char_referenceRc
119+
// CHECK: store ptr %a, ptr
120+
// CHECK: load ptr, ptr
121+
// CHECK-NOT: call i8 @llvm.bswap.i8
122+
// CHECK: ret void

clang/test/Sema/constant-builtins-2.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,10 @@ int h6 = __builtin_bswapg((char)(0x12)) == (char)(0x12) ? 1 : f();
483483
int h7 = __builtin_bswapg((short)(0x1234)) == (short)(0x3412) ? 1 : f();
484484
int h8 = __builtin_bswapg(0x00001234) == 0x34120000 ? 1 : f();
485485
int h9 = __builtin_bswapg(0x0000000000001234ULL) == 0x3412000000000000 ? 1 : f();
486+
float h10 = __builtin_bswapg(1.0f); // expected-error {{1st argument must be a scalar integer type (was 'float')}}
487+
double h12 = __builtin_bswapg(1.0L); // expected-error {{1st argument must be a scalar integer type (was 'long double')}}
488+
char *h13 = __builtin_bswapg("hello"); // expected-error {{1st argument must be a scalar integer type (was 'char[6]')}}
489+
int h14 = __builtin_bswapg(1, 2); // expected-error {{too many arguments to function call, expected 1, have 2}}
486490
extern long int bi0;
487491
extern __typeof__(__builtin_expect(0, 0)) bi0;
488492

clang/test/SemaCXX/builtin-bswapg.cpp

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// RUN: %clang_cc1 -fsyntax-only -verify %s
22
// RUN: %clang_cc1 -fsyntax-only -verify -fexperimental-new-constant-interpreter %s
3-
// expected-no-diagnostics
43

54
void test_basic_type_checks() {
65
static_assert(__is_same(char, decltype(__builtin_bswapg((char)0))), "");
@@ -83,3 +82,79 @@ template struct ValueTemplateTypeTest<0x1234>;
8382
template struct ValueTemplateTypeTest<0x12345678UL>;
8483
template struct ValueTemplateTypeTest<(short)0x1234>;
8584
template struct ValueTemplateTypeTest<(char)0x12>;
85+
86+
template<typename T>
87+
void test_invalid_type() {
88+
__builtin_bswapg(T{}); // #invalid_type_use
89+
}
90+
91+
void test_basic_errors() {
92+
test_invalid_type<float>();
93+
// expected-note@-1 {{in instantiation of function template specialization 'test_invalid_type<float>' requested here}}
94+
// expected-error@#invalid_type_use {{1st argument must be a scalar integer type (was 'float')}}
95+
96+
test_invalid_type<double>();
97+
// expected-note@-1 {{in instantiation of function template specialization 'test_invalid_type<double>' requested here}}
98+
// expected-error@#invalid_type_use {{1st argument must be a scalar integer type (was 'double')}}
99+
100+
test_invalid_type<void*>();
101+
// expected-note@-1 {{in instantiation of function template specialization 'test_invalid_type<void *>' requested here}}
102+
// expected-error@#invalid_type_use {{1st argument must be a scalar integer type (was 'void *')}}
103+
}
104+
105+
template<typename T>
106+
auto test_dependent_context(T value) -> decltype(__builtin_bswapg(value)) { // #dependent_use
107+
return __builtin_bswapg(value);
108+
}
109+
110+
void test_dependent_errors() {
111+
test_dependent_context(1.0f);
112+
// expected-error@-1 {{no matching function for call to 'test_dependent_context'}}
113+
// expected-note@#dependent_use {{candidate template ignored: substitution failure [with T = float]: 1st argument must be a scalar integer type (was 'float')}}
114+
test_dependent_context(1.0l);
115+
// expected-error@-1 {{no matching function for call to 'test_dependent_context'}}
116+
// expected-note@#dependent_use {{candidate template ignored: substitution failure [with T = long double]: 1st argument must be a scalar integer type (was 'long double')}}
117+
test_dependent_context("hello");
118+
// expected-error@-1 {{no matching function for call to 'test_dependent_context'}}
119+
// expected-note@#dependent_use {{candidate template ignored: substitution failure [with T = const char *]: 1st argument must be a scalar integer type (was 'const char *')}}
120+
}
121+
122+
void test_lambda_errors() {
123+
auto lambda = [](auto x) {
124+
return __builtin_bswapg(x); // #lambda_use
125+
};
126+
127+
lambda(1.0f);
128+
// expected-error@#lambda_use {{1st argument must be a scalar integer type (was 'float')}}
129+
// expected-note@-2 {{in instantiation of function template specialization 'test_lambda_errors()::(anonymous class)::operator()<float>' requested here}}
130+
lambda(1.0l);
131+
// expected-error@#lambda_use {{1st argument must be a scalar integer type (was 'long double')}}
132+
// expected-note@-2 {{in instantiation of function template specialization 'test_lambda_errors()::(anonymous class)::operator()<long double>' requested here}}
133+
lambda("hello");
134+
// expected-error@#lambda_use {{1st argument must be a scalar integer type (was 'const char *')}}
135+
// expected-note@-2 {{in instantiation of function template specialization 'test_lambda_errors()::(anonymous class)::operator()<const char *>' requested here}}
136+
}
137+
138+
void test_argument_count_errors() {
139+
int h14 = __builtin_bswapg(1, 2); // expected-error {{too many arguments to function call, expected 1, have 2}}
140+
}
141+
142+
void test_lvalue_reference(int& a) {
143+
auto result = __builtin_bswapg(a);
144+
static_assert(__is_same(int, decltype(result)), "Should decay reference to value type");
145+
}
146+
147+
void test_const_lvalue_reference(const int& a) {
148+
auto result = __builtin_bswapg(a);
149+
static_assert(__is_same(int, decltype(result)), "Should decay const reference to value type");
150+
}
151+
152+
void test_rvalue_reference(int&& a) {
153+
auto result = __builtin_bswapg(a);
154+
static_assert(__is_same(int, decltype(result)), "Should decay rvalue reference to value type");
155+
}
156+
157+
void test_const_rvalue_reference(const int&& a) {
158+
auto result = __builtin_bswapg(a);
159+
static_assert(__is_same(int, decltype(result)), "Should decay const rvalue reference to value type");
160+
}

0 commit comments

Comments
 (0)