Skip to content

Commit 3dbcea8

Browse files
committed
Reland [clang] Check unsupported types in expressions
This was committed as ec6c847, but then reverted after a failure in: https://lab.llvm.org/buildbot/#/builders/84/builds/13983 I was not able to reproduce the problem, but I added an extra check for a NULL QualType just in case. Original comit message: The patch adds missing diagnostics for cases like: float F3 = ((__float128)F1 * (__float128)F2) / 2.0f; Sema::checkDeviceDecl (renamed to checkTypeSupport) is changed to work with a type without the corresponding ValueDecl. It is also refactored so that host diagnostics for unsupported types can be added here as well. Differential Revision: https://reviews.llvm.org/D109315
1 parent 2712d18 commit 3dbcea8

File tree

9 files changed

+111
-72
lines changed

9 files changed

+111
-72
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10713,8 +10713,8 @@ def err_omp_invariant_or_linear_dependency : Error<
1071310713
"expected loop invariant expression or '<invariant1> * %0 + <invariant2>' kind of expression">;
1071410714
def err_omp_wrong_dependency_iterator_type : Error<
1071510715
"expected an integer or a pointer type of the outer loop counter '%0' for non-rectangular nests">;
10716-
def err_device_unsupported_type
10717-
: Error<"%0 requires %select{|%2 bit size}1 %3 type support, but device "
10716+
def err_target_unsupported_type
10717+
: Error<"%0 requires %select{|%2 bit size}1 %3 type support, but target "
1071810718
"'%4' does not support it">;
1071910719
def err_omp_lambda_capture_in_declare_target_not_to : Error<
1072010720
"variable captured in declare target region must appear in a to clause">;

clang/include/clang/Sema/Sema.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12219,9 +12219,9 @@ class Sema final {
1221912219
return targetDiag(Loc, PD.getDiagID(), FD) << PD;
1222012220
}
1222112221

12222-
/// Check if the expression is allowed to be used in expressions for the
12223-
/// offloading devices.
12224-
void checkDeviceDecl(ValueDecl *D, SourceLocation Loc);
12222+
/// Check if the type is allowed to be used for the current target.
12223+
void checkTypeSupport(QualType Ty, SourceLocation Loc,
12224+
ValueDecl *D = nullptr);
1222512225

1222612226
enum CUDAFunctionTarget {
1222712227
CFT_Device,

clang/lib/Sema/Sema.cpp

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1854,8 +1854,11 @@ Sema::SemaDiagnosticBuilder Sema::Diag(SourceLocation Loc, unsigned DiagID,
18541854
return DB;
18551855
}
18561856

1857-
void Sema::checkDeviceDecl(ValueDecl *D, SourceLocation Loc) {
1858-
if (isUnevaluatedContext())
1857+
void Sema::checkTypeSupport(QualType Ty, SourceLocation Loc, ValueDecl *D) {
1858+
if (!LangOpts.SYCLIsDevice && !(LangOpts.OpenMP && LangOpts.OpenMPIsDevice))
1859+
return;
1860+
1861+
if (isUnevaluatedContext() || Ty.isNull())
18591862
return;
18601863

18611864
Decl *C = cast<Decl>(getCurLexicalContext());
@@ -1874,16 +1877,22 @@ void Sema::checkDeviceDecl(ValueDecl *D, SourceLocation Loc) {
18741877

18751878
// Try to associate errors with the lexical context, if that is a function, or
18761879
// the value declaration otherwise.
1877-
FunctionDecl *FD =
1878-
isa<FunctionDecl>(C) ? cast<FunctionDecl>(C) : dyn_cast<FunctionDecl>(D);
1880+
FunctionDecl *FD = isa<FunctionDecl>(C) ? cast<FunctionDecl>(C)
1881+
: dyn_cast_or_null<FunctionDecl>(D);
1882+
18791883
auto CheckType = [&](QualType Ty) {
18801884
if (Ty->isDependentType())
18811885
return;
18821886

18831887
if (Ty->isExtIntType()) {
18841888
if (!Context.getTargetInfo().hasExtIntType()) {
1885-
targetDiag(Loc, diag::err_device_unsupported_type, FD)
1886-
<< D << false /*show bit size*/ << 0 /*bitsize*/
1889+
PartialDiagnostic PD = PDiag(diag::err_target_unsupported_type);
1890+
if (D)
1891+
PD << D;
1892+
else
1893+
PD << "expression";
1894+
targetDiag(Loc, PD, FD)
1895+
<< false /*show bit size*/ << 0 /*bitsize*/
18871896
<< Ty << Context.getTargetInfo().getTriple().str();
18881897
}
18891898
return;
@@ -1907,16 +1916,24 @@ void Sema::checkDeviceDecl(ValueDecl *D, SourceLocation Loc) {
19071916
(Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 &&
19081917
!Context.getTargetInfo().hasInt128Type()) ||
19091918
LongDoubleMismatched) {
1910-
if (targetDiag(Loc, diag::err_device_unsupported_type, FD)
1911-
<< D << true /*show bit size*/
1919+
PartialDiagnostic PD = PDiag(diag::err_target_unsupported_type);
1920+
if (D)
1921+
PD << D;
1922+
else
1923+
PD << "expression";
1924+
1925+
if (targetDiag(Loc, PD, FD)
1926+
<< true /*show bit size*/
19121927
<< static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty
1913-
<< Context.getTargetInfo().getTriple().str())
1914-
D->setInvalidDecl();
1915-
targetDiag(D->getLocation(), diag::note_defined_here, FD) << D;
1928+
<< Context.getTargetInfo().getTriple().str()) {
1929+
if (D)
1930+
D->setInvalidDecl();
1931+
}
1932+
if (D)
1933+
targetDiag(D->getLocation(), diag::note_defined_here, FD) << D;
19161934
}
19171935
};
19181936

1919-
QualType Ty = D->getType();
19201937
CheckType(Ty);
19211938

19221939
if (const auto *FPTy = dyn_cast<FunctionProtoType>(Ty)) {

clang/lib/Sema/SemaDecl.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9570,8 +9570,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
95709570
}
95719571
}
95729572

9573-
if (LangOpts.SYCLIsDevice || (LangOpts.OpenMP && LangOpts.OpenMPIsDevice))
9574-
checkDeviceDecl(NewFD, D.getBeginLoc());
9573+
checkTypeSupport(NewFD->getType(), D.getBeginLoc(), NewFD);
95759574

95769575
if (!getLangOpts().CPlusPlus) {
95779576
// Perform semantic checking on the function declaration.

clang/lib/Sema/SemaExpr.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -368,10 +368,10 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
368368

369369
diagnoseUseOfInternalDeclInInlineFunction(*this, D, Loc);
370370

371-
if (LangOpts.SYCLIsDevice || (LangOpts.OpenMP && LangOpts.OpenMPIsDevice)) {
372-
if (auto *VD = dyn_cast<ValueDecl>(D))
373-
checkDeviceDecl(VD, Loc);
371+
if (auto *VD = dyn_cast<ValueDecl>(D))
372+
checkTypeSupport(VD->getType(), Loc, VD);
374373

374+
if (LangOpts.SYCLIsDevice || (LangOpts.OpenMP && LangOpts.OpenMPIsDevice)) {
375375
if (!Context.getTargetInfo().isTLSSupported())
376376
if (const auto *VD = dyn_cast<VarDecl>(D))
377377
if (VD->getTLSKind() != VarDecl::TLS_None)
@@ -14165,6 +14165,9 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
1416514165
}
1416614166
}
1416714167

14168+
checkTypeSupport(LHSExpr->getType(), OpLoc, /*ValueDecl*/ nullptr);
14169+
checkTypeSupport(RHSExpr->getType(), OpLoc, /*ValueDecl*/ nullptr);
14170+
1416814171
switch (Opc) {
1416914172
case BO_Assign:
1417014173
ResultTy = CheckAssignmentOperands(LHS.get(), RHS, OpLoc, QualType());

clang/test/CodeGen/ibm128-unsupported.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ void foo(__ibm128 x); // expected-note {{'foo' defined here}}
99
void loop(int n, __ibm128 *arr) {
1010
#pragma omp target parallel
1111
for (int i = 0; i < n; ++i) {
12-
// expected-error@+1 {{'foo' requires 128 bit size '__ibm128' type support, but device 'x86_64' does not support it}}
12+
// expected-error@+1 {{'foo' requires 128 bit size '__ibm128' type support, but target 'x86_64' does not support it}}
1313
foo(arr[i]);
1414
}
1515
}

clang/test/OpenMP/nvptx_unsupported_type_messages.cpp

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ struct T {
1616
char c;
1717
T() : a(12), f(15) {}
1818
#ifndef _ARCH_PPC
19-
// expected-error@+5 {{'f' requires 128 bit size '__float128' type support, but device 'nvptx64-unknown-unknown' does not support it}}
19+
// expected-error@+7 {{'f' requires 128 bit size '__float128' type support, but target 'nvptx64-unknown-unknown' does not support it}}
20+
// expected-error@+6 {{expression requires 128 bit size '__float128' type support, but target 'nvptx64-unknown-unknown' does not support it}}
2021
#else
21-
// expected-error@+3 {{'f' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}}
22+
// expected-error@+4 {{'f' requires 128 bit size 'long double' type support, but target 'nvptx64-unknown-unknown' does not support it}}
23+
// expected-error@+3 {{expression requires 128 bit size 'long double' type support, but target 'nvptx64-unknown-unknown' does not support it}}
2224
#endif
2325
T &operator+(T &b) {
2426
f += b.a;
@@ -39,11 +41,11 @@ struct T1 {
3941
};
4042

4143
#ifndef _ARCH_PPC
42-
// expected-error@+2 {{'boo' requires 128 bit size '__float128' type support, but device 'nvptx64-unknown-unknown' does not support it}}
44+
// expected-error@+2 {{'boo' requires 128 bit size '__float128' type support, but target 'nvptx64-unknown-unknown' does not support it}}
4345
// expected-note@+1 2{{'boo' defined here}}
4446
void boo(__float128 A) { return; }
4547
#else
46-
// expected-error@+2 {{'boo' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}}
48+
// expected-error@+2 {{'boo' requires 128 bit size 'long double' type support, but target 'nvptx64-unknown-unknown' does not support it}}
4749
// expected-note@+1 2{{'boo' defined here}}
4850
void boo(long double A) { return; }
4951
#endif
@@ -53,9 +55,9 @@ T f = a;
5355
void foo(T a = T()) {
5456
a = a + f; // expected-note {{called by 'foo'}}
5557
#ifndef _ARCH_PPC
56-
// expected-error@+5 {{'boo' requires 128 bit size '__float128' type support, but device 'nvptx64-unknown-unknown' does not support it}}
58+
// expected-error@+5 {{'boo' requires 128 bit size '__float128' type support, but target 'nvptx64-unknown-unknown' does not support it}}
5759
#else
58-
// expected-error@+3 {{'boo' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}}
60+
// expected-error@+3 {{'boo' requires 128 bit size 'long double' type support, but target 'nvptx64-unknown-unknown' does not support it}}
5961
#endif
6062
// expected-note@+1 {{called by 'foo'}}
6163
boo(0);
@@ -96,18 +98,18 @@ void dead_template_declare_target() {
9698
}
9799

98100
// expected-note@+2 {{'ld_return1a' defined here}}
99-
// expected-error@+1 {{'ld_return1a' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}}
101+
// expected-error@+1 {{'ld_return1a' requires 128 bit size 'long double' type support, but target 'nvptx64-unknown-unknown' does not support it}}
100102
long double ld_return1a() { return 0; }
101103
// expected-note@+2 {{'ld_arg1a' defined here}}
102-
// expected-error@+1 {{'ld_arg1a' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}}
104+
// expected-error@+1 {{'ld_arg1a' requires 128 bit size 'long double' type support, but target 'nvptx64-unknown-unknown' does not support it}}
103105
void ld_arg1a(long double ld) {}
104106

105107
typedef long double ld_ty;
106108
// expected-note@+2 {{'ld_return1b' defined here}}
107-
// expected-error@+1 {{'ld_return1b' requires 128 bit size 'ld_ty' (aka 'long double') type support, but device 'nvptx64-unknown-unknown' does not support it}}
109+
// expected-error@+1 {{'ld_return1b' requires 128 bit size 'ld_ty' (aka 'long double') type support, but target 'nvptx64-unknown-unknown' does not support it}}
108110
ld_ty ld_return1b() { return 0; }
109111
// expected-note@+2 {{'ld_arg1b' defined here}}
110-
// expected-error@+1 {{'ld_arg1b' requires 128 bit size 'ld_ty' (aka 'long double') type support, but device 'nvptx64-unknown-unknown' does not support it}}
112+
// expected-error@+1 {{'ld_arg1b' requires 128 bit size 'ld_ty' (aka 'long double') type support, but target 'nvptx64-unknown-unknown' does not support it}}
111113
void ld_arg1b(ld_ty ld) {}
112114

113115
static long double ld_return1c() { return 0; }
@@ -138,24 +140,26 @@ static void ld_use2() {
138140
inline void ld_use3() {
139141
// expected-note@+1 {{'ld' defined here}}
140142
long double ld = 0;
141-
// expected-error@+1 {{'ld' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}}
143+
// expected-error@+2 {{expression requires 128 bit size 'long double' type support, but target 'nvptx64-unknown-unknown' does not support it}}
144+
// expected-error@+1 {{'ld' requires 128 bit size 'long double' type support, but target 'nvptx64-unknown-unknown' does not support it}}
142145
ld += 1;
143146
}
144147
static void ld_use4() {
145148
// expected-note@+1 {{'ld' defined here}}
146149
long double ld = 0;
147-
// expected-error@+1 {{'ld' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}}
150+
// expected-error@+2 {{expression requires 128 bit size 'long double' type support, but target 'nvptx64-unknown-unknown' does not support it}}
151+
// expected-error@+1 {{'ld' requires 128 bit size 'long double' type support, but target 'nvptx64-unknown-unknown' does not support it}}
148152
ld += 1;
149153
}
150154

151155
void external() {
152-
// expected-error@+1 {{'ld_return1e' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}}
156+
// expected-error@+1 {{'ld_return1e' requires 128 bit size 'long double' type support, but target 'nvptx64-unknown-unknown' does not support it}}
153157
void *p1 = reinterpret_cast<void*>(&ld_return1e);
154-
// expected-error@+1 {{'ld_arg1e' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}}
158+
// expected-error@+1 {{'ld_arg1e' requires 128 bit size 'long double' type support, but target 'nvptx64-unknown-unknown' does not support it}}
155159
void *p2 = reinterpret_cast<void*>(&ld_arg1e);
156-
// expected-error@+1 {{'ld_return1f' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}}
160+
// expected-error@+1 {{'ld_return1f' requires 128 bit size 'long double' type support, but target 'nvptx64-unknown-unknown' does not support it}}
157161
void *p3 = reinterpret_cast<void*>(&ld_return1f);
158-
// expected-error@+1 {{'ld_arg1f' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}}
162+
// expected-error@+1 {{'ld_arg1f' requires 128 bit size 'long double' type support, but target 'nvptx64-unknown-unknown' does not support it}}
159163
void *p4 = reinterpret_cast<void*>(&ld_arg1f);
160164
// TODO: The error message "called by" is not great.
161165
// expected-note@+1 {{called by 'external'}}
@@ -166,18 +170,18 @@ void external() {
166170

167171
#ifndef _ARCH_PPC
168172
// expected-note@+2 {{'ld_return2a' defined here}}
169-
// expected-error@+1 {{'ld_return2a' requires 128 bit size '__float128' type support, but device 'nvptx64-unknown-unknown' does not support it}}
173+
// expected-error@+1 {{'ld_return2a' requires 128 bit size '__float128' type support, but target 'nvptx64-unknown-unknown' does not support it}}
170174
__float128 ld_return2a() { return 0; }
171175
// expected-note@+2 {{'ld_arg2a' defined here}}
172-
// expected-error@+1 {{'ld_arg2a' requires 128 bit size '__float128' type support, but device 'nvptx64-unknown-unknown' does not support it}}
176+
// expected-error@+1 {{'ld_arg2a' requires 128 bit size '__float128' type support, but target 'nvptx64-unknown-unknown' does not support it}}
173177
void ld_arg2a(__float128 ld) {}
174178

175179
typedef __float128 fp128_ty;
176180
// expected-note@+2 {{'ld_return2b' defined here}}
177-
// expected-error@+1 {{'ld_return2b' requires 128 bit size 'fp128_ty' (aka '__float128') type support, but device 'nvptx64-unknown-unknown' does not support it}}
181+
// expected-error@+1 {{'ld_return2b' requires 128 bit size 'fp128_ty' (aka '__float128') type support, but target 'nvptx64-unknown-unknown' does not support it}}
178182
fp128_ty ld_return2b() { return 0; }
179183
// expected-note@+2 {{'ld_arg2b' defined here}}
180-
// expected-error@+1 {{'ld_arg2b' requires 128 bit size 'fp128_ty' (aka '__float128') type support, but device 'nvptx64-unknown-unknown' does not support it}}
184+
// expected-error@+1 {{'ld_arg2b' requires 128 bit size 'fp128_ty' (aka '__float128') type support, but target 'nvptx64-unknown-unknown' does not support it}}
181185
void ld_arg2b(fp128_ty ld) {}
182186
#endif
183187

@@ -187,7 +191,7 @@ void ld_arg2b(fp128_ty ld) {}
187191
// expected-note@+1 {{'f' defined here}}
188192
inline long double dead_inline(long double f) {
189193
#pragma omp target map(f)
190-
// expected-error@+1 {{'f' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}}
194+
// expected-error@+1 {{'f' requires 128 bit size 'long double' type support, but target 'nvptx64-unknown-unknown' does not support it}}
191195
f = 1;
192196
return f;
193197
}
@@ -196,7 +200,7 @@ inline long double dead_inline(long double f) {
196200
// expected-note@+1 {{'f' defined here}}
197201
static long double dead_static(long double f) {
198202
#pragma omp target map(f)
199-
// expected-error@+1 {{'f' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}}
203+
// expected-error@+1 {{'f' requires 128 bit size 'long double' type support, but target 'nvptx64-unknown-unknown' does not support it}}
200204
f = 1;
201205
return f;
202206
}
@@ -212,15 +216,15 @@ long double dead_template(long double f) {
212216
// expected-note@+1 {{'f' defined here}}
213217
__float128 foo2(__float128 f) {
214218
#pragma omp target map(f)
215-
// expected-error@+1 {{'f' requires 128 bit size '__float128' type support, but device 'nvptx64-unknown-unknown' does not support it}}
219+
// expected-error@+1 {{'f' requires 128 bit size '__float128' type support, but target 'nvptx64-unknown-unknown' does not support it}}
216220
f = 1;
217221
return f;
218222
}
219223
#else
220224
// expected-note@+1 {{'f' defined here}}
221225
long double foo3(long double f) {
222226
#pragma omp target map(f)
223-
// expected-error@+1 {{'f' requires 128 bit size 'long double' type support, but device 'nvptx64-unknown-unknown' does not support it}}
227+
// expected-error@+1 {{'f' requires 128 bit size 'long double' type support, but target 'nvptx64-unknown-unknown' does not support it}}
224228
f = 1;
225229
return f;
226230
}

0 commit comments

Comments
 (0)