[OpenCL] Reject virtual functions for OpenCL C++

Differential Revision: https://reviews.llvm.org/D45873

llvm-svn: 330579
This commit is contained in:
Sven van Haastregt 2018-04-23 11:23:47 +00:00
parent 691d134805
commit 49ffffbccd
5 changed files with 60 additions and 1 deletions

View File

@ -1073,6 +1073,10 @@ def err_opencl_taking_function_address_parser : Error<
def err_opencl_logical_exclusive_or : Error< def err_opencl_logical_exclusive_or : Error<
"^^ is a reserved operator in OpenCL">; "^^ is a reserved operator in OpenCL">;
// OpenCL C++.
def err_openclcxx_virtual_function : Error<
"virtual functions are not supported in OpenCL C++">;
// OpenMP support. // OpenMP support.
def warn_pragma_omp_ignored : Warning< def warn_pragma_omp_ignored : Warning<
"unexpected '#pragma omp ...' in program">, InGroup<SourceUsesOpenMP>, DefaultIgnore; "unexpected '#pragma omp ...' in program">, InGroup<SourceUsesOpenMP>, DefaultIgnore;

View File

@ -189,6 +189,7 @@ LANGOPT(ShortEnums , 1, 0, "short enum types")
LANGOPT(OpenCL , 1, 0, "OpenCL") LANGOPT(OpenCL , 1, 0, "OpenCL")
LANGOPT(OpenCLVersion , 32, 0, "OpenCL C version") LANGOPT(OpenCLVersion , 32, 0, "OpenCL C version")
LANGOPT(OpenCLCPlusPlus , 1, 0, "OpenCL C++")
LANGOPT(OpenCLCPlusPlusVersion , 32, 0, "OpenCL C++ version") LANGOPT(OpenCLCPlusPlusVersion , 32, 0, "OpenCL C++ version")
LANGOPT(NativeHalfType , 1, 0, "Native half type support") LANGOPT(NativeHalfType , 1, 0, "Native half type support")
LANGOPT(NativeHalfArgsAndReturns, 1, 0, "Native half args and returns") LANGOPT(NativeHalfArgsAndReturns, 1, 0, "Native half args and returns")

View File

@ -1927,6 +1927,7 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
Opts.setDefaultFPContractMode(LangOptions::FPC_On); Opts.setDefaultFPContractMode(LangOptions::FPC_On);
Opts.NativeHalfType = 1; Opts.NativeHalfType = 1;
Opts.NativeHalfArgsAndReturns = 1; Opts.NativeHalfArgsAndReturns = 1;
Opts.OpenCLCPlusPlus = Opts.CPlusPlus;
// Include default header file for OpenCL. // Include default header file for OpenCL.
if (Opts.IncludeDefaultHeader) { if (Opts.IncludeDefaultHeader) {
PPOpts.Includes.push_back("opencl-c.h"); PPOpts.Includes.push_back("opencl-c.h");

View File

@ -3466,7 +3466,15 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
isInvalid = DS.setFunctionSpecInline(Loc, PrevSpec, DiagID); isInvalid = DS.setFunctionSpecInline(Loc, PrevSpec, DiagID);
break; break;
case tok::kw_virtual: case tok::kw_virtual:
isInvalid = DS.setFunctionSpecVirtual(Loc, PrevSpec, DiagID); // OpenCL C++ v1.0 s2.9: the virtual function qualifier is not supported.
if (getLangOpts().OpenCLCPlusPlus) {
DiagID = diag::err_openclcxx_virtual_function;
PrevSpec = Tok.getIdentifierInfo()->getNameStart();
isInvalid = true;
}
else {
isInvalid = DS.setFunctionSpecVirtual(Loc, PrevSpec, DiagID);
}
break; break;
case tok::kw_explicit: case tok::kw_explicit:
isInvalid = DS.setFunctionSpecExplicit(Loc, PrevSpec, DiagID); isInvalid = DS.setFunctionSpecExplicit(Loc, PrevSpec, DiagID);

View File

@ -0,0 +1,45 @@
// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -fsyntax-only -verify
// Test that virtual functions and abstract classes are rejected.
class virtual_functions {
virtual void bad1() {}
//expected-error@-1 {{virtual functions are not supported in OpenCL C++}}
virtual void bad2() = 0;
//expected-error@-1 {{virtual functions are not supported in OpenCL C++}}
//expected-error@-2 {{'bad2' is not virtual and cannot be declared pure}}
};
template <typename T>
class X {
virtual T f();
//expected-error@-1 {{virtual functions are not supported in OpenCL C++}}
};
// Test that virtual base classes are allowed.
struct A {
int a;
void foo();
};
struct B : virtual A {
int b;
};
struct C : public virtual A {
int c;
};
struct D : B, C {
int d;
};
kernel void virtual_inheritance() {
D d;
d.foo();
d.a = 11;
d.b = 22;
d.c = 33;
d.d = 44;
}