Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -8841,6 +8841,9 @@ // inline asm. let CategoryName = "Inline Assembly Issue" in { + def err_asm_pmf_through_constraint_not_permitted + : Error<"passing pointer-to-member through register constrained inline " + "assembly parameter is not permitted">; def err_asm_invalid_lvalue_in_output : Error<"invalid lvalue in asm output">; def err_asm_invalid_output_constraint : Error< "invalid output constraint '%0' in asm">; Index: clang/lib/Sema/SemaStmtAsm.cpp =================================================================== --- clang/lib/Sema/SemaStmtAsm.cpp +++ clang/lib/Sema/SemaStmtAsm.cpp @@ -377,6 +377,11 @@ Expr *InputExpr = Exprs[i]; + if (InputExpr->getType()->isMemberPointerType()) + return StmtError(Diag(InputExpr->getBeginLoc(), + diag::err_asm_pmf_through_constraint_not_permitted) + << InputExpr->getSourceRange()); + // Referring to parameters is not allowed in naked functions. if (CheckNakedParmReference(InputExpr, *this)) return StmtError(); Index: clang/test/Sema/gnu-asm-pmf.cpp =================================================================== --- /dev/null +++ clang/test/Sema/gnu-asm-pmf.cpp @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -std=c++2b -fsyntax-only %s -verify +// RUN: %clang_cc1 -triple x86_64-unknown-windows-itanium -std=c++2b -fsyntax-only %s -verify + +struct S { + void operator()(); +}; + +struct T { + virtual void operator()(); +}; + +struct U { + static void operator()(); +}; + +struct V: virtual T { + virtual void f(); +}; + +struct W : virtual V { + int i; +}; + +struct X { + __UINTPTR_TYPE__ ptr; + __UINTPTR_TYPE__ adj; +}; + +auto L = [](){}; + +void f() { + auto pmf = &S::operator(); + + __asm__ __volatile__ ("" : : "r"(&decltype(L)::operator())); + // expected-error@-1{{passing pointer-to-member through register constrained inline assembly parameter is not permitted}} + __asm__ __volatile__ ("" : : "r"(&S::operator())); + // expected-error@-1{{passing pointer-to-member through register constrained inline assembly parameter is not permitted}} + __asm__ __volatile__ ("" : : "r"(&T::operator())); + // expected-error@-1{{passing pointer-to-member through register constrained inline assembly parameter is not permitted}} + __asm__ __volatile__ ("" : : "r"(pmf)); + // expected-error@-1{{passing pointer-to-member through register constrained inline assembly parameter is not permitted}} + __asm__ __volatile__ ("" : : "r"(&W::f)); + // expected-error@-1{{passing pointer-to-member through register constrained inline assembly parameter is not permitted}} + __asm__ __volatile__ ("" : : "r"(&W::i)); + // expected-error@-1{{passing pointer-to-member through register constrained inline assembly parameter is not permitted}} + + __asm__ __volatile__ ("" : : "r"(X{0,0})); + __asm__ __volatile__ ("" : : "r"(&U::operator())); +}