From 696f6bbbf87eecdf43218266a54995bee361e9e9 Mon Sep 17 00:00:00 2001 From: Justin Lebar Date: Tue, 22 Mar 2016 22:06:19 +0000 Subject: [PATCH] [CUDA] Don't allow templated variadic functions. Reviewers: tra Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D18373 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@264106 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDecl.cpp | 44 ++++++++++++++++++++--------------------- test/SemaCUDA/vararg.cu | 6 ++++++ 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 321f1006bf..65ca8dd44d 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -8341,6 +8341,28 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, isExplicitSpecialization || isFunctionTemplateSpecialization); } + if (getLangOpts().CUDA) { + IdentifierInfo *II = NewFD->getIdentifier(); + if (II && II->isStr("cudaConfigureCall") && !NewFD->isInvalidDecl() && + NewFD->getDeclContext()->getRedeclContext()->isTranslationUnit()) { + if (!R->getAs()->getReturnType()->isScalarType()) + Diag(NewFD->getLocation(), diag::err_config_scalar_return); + + Context.setcudaConfigureCallDecl(NewFD); + } + + // Variadic functions, other than a *declaration* of printf, are not allowed + // in device-side CUDA code, unless someone passed + // -fcuda-allow-variadic-functions. + if (!getLangOpts().CUDAAllowVariadicFunctions && NewFD->isVariadic() && + (NewFD->hasAttr() || + NewFD->hasAttr()) && + !(II && II->isStr("printf") && NewFD->isExternC() && + !D.isFunctionDefinition())) { + Diag(NewFD->getLocation(), diag::err_variadic_device_fn); + } + } + if (getLangOpts().CPlusPlus) { if (FunctionTemplate) { if (NewFD->isInvalidDecl()) @@ -8390,28 +8412,6 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, MarkUnusedFileScopedDecl(NewFD); - if (getLangOpts().CUDA) { - IdentifierInfo *II = NewFD->getIdentifier(); - if (II && II->isStr("cudaConfigureCall") && !NewFD->isInvalidDecl() && - NewFD->getDeclContext()->getRedeclContext()->isTranslationUnit()) { - if (!R->getAs()->getReturnType()->isScalarType()) - Diag(NewFD->getLocation(), diag::err_config_scalar_return); - - Context.setcudaConfigureCallDecl(NewFD); - } - - // Variadic functions, other than a *declaration* of printf, are not allowed - // in device-side CUDA code, unless someone passed - // -fcuda-allow-variadic-functions. - if (!getLangOpts().CUDAAllowVariadicFunctions && NewFD->isVariadic() && - (NewFD->hasAttr() || - NewFD->hasAttr()) && - !(II && II->isStr("printf") && NewFD->isExternC() && - !D.isFunctionDefinition())) { - Diag(NewFD->getLocation(), diag::err_variadic_device_fn); - } - } - // Here we have an function template explicit specialization at class scope. // The actually specialization will be postponed to template instatiation // time via the ClassScopeFunctionSpecializationDecl node. diff --git a/test/SemaCUDA/vararg.cu b/test/SemaCUDA/vararg.cu index c14d489145..34ef367d89 100644 --- a/test/SemaCUDA/vararg.cu +++ b/test/SemaCUDA/vararg.cu @@ -35,6 +35,12 @@ __device__ void vararg(const char* x, ...) {} // expected-error@-2 {{CUDA device code does not support variadic functions}} #endif +template +__device__ void vararg(T t, ...) {} +#ifdef EXPECT_VARARG_ERR +// expected-error@-2 {{CUDA device code does not support variadic functions}} +#endif + extern "C" __device__ int printf(const char* fmt, ...); // OK, special case. // Definition of printf not allowed. -- 2.40.0