Index: include/clang/AST/ExprCXX.h =================================================================== --- include/clang/AST/ExprCXX.h +++ include/clang/AST/ExprCXX.h @@ -155,6 +155,7 @@ class CUDAKernelCallExpr : public CallExpr { private: enum { CONFIG, END_PREARG }; + bool IsConfigSet = false; public: CUDAKernelCallExpr(ASTContext &C, Expr *fn, CallExpr *Config, @@ -171,7 +172,19 @@ return cast_or_null(getPreArg(CONFIG)); } CallExpr *getConfig() { return cast_or_null(getPreArg(CONFIG)); } - void setConfig(CallExpr *E) { setPreArg(CONFIG, E); } + + /// \brief Sets the kernel configuration expression. + /// + /// Note that this method can only be called once per class instance. + void setConfig(CallExpr *E) { + assert( + !IsConfigSet && + "CUDAKernelCallExpr.setConfig can only be called once per instance."); + setPreArg(CONFIG, E); + setInstantiationDependent(isInstantiationDependent() || + E->isInstantiationDependent()); + IsConfigSet = true; + } static bool classof(const Stmt *T) { return T->getStmtClass() == CUDAKernelCallExprClass; Index: test/SemaCUDA/kernel-call.cu =================================================================== --- test/SemaCUDA/kernel-call.cu +++ test/SemaCUDA/kernel-call.cu @@ -23,4 +23,6 @@ int (*fp)(int) = h2; fp<<<1, 1>>>(42); // expected-error {{must have void return type}} + + g1<<>>(42); // expected-error {{use of undeclared identifier 'undeclared'}} }