Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -4604,14 +4604,40 @@ static void handleXRayLogArgsAttr(Sema &S, Decl *D, const AttributeList &Attr) { uint64_t ArgCount; + + // Treat member functions especially, since we do want to support saving the + // implicit this argument for member functions. + if (isInstanceMethod(D)) { + auto *IdxExpr = Attr.getArgAsExpr(0); + llvm::APSInt IdxInt; + if (!IdxExpr->isIntegerConstantExpr(IdxInt, S.Context)) { + S.Diag(getAttrLoc(Attr), diag::err_attribute_argument_n_type) + << getAttrName(Attr) << 1u << AANT_ArgumentIntegerConstant + << IdxExpr->getSourceRange(); + return; + } + ArgCount = IdxInt.getLimitedValue(); + bool HP = hasFunctionProto(D); + unsigned NumParams = HP ? getFunctionOrMethodNumParams(D) + 1 : 1; + if (ArgCount > NumParams) { + S.Diag(getAttrLoc(Attr), diag::err_attribute_argument_out_of_bounds) + << getAttrName(Attr) << 1 << IdxExpr->getSourceRange(); + return; + } + D->addAttr(::new (S.Context) + XRayLogArgsAttr(Attr.getRange(), S.Context, ArgCount, + Attr.getAttributeSpellingListIndex())); + return; + } + if (!checkFunctionOrMethodParameterIndex(S, D, Attr, 1, Attr.getArgAsExpr(0), ArgCount)) return; // ArgCount isn't a parameter index [0;n), it's a count [1;n] - hence + 1. D->addAttr(::new (S.Context) - XRayLogArgsAttr(Attr.getRange(), S.Context, ++ArgCount, - Attr.getAttributeSpellingListIndex())); + XRayLogArgsAttr(Attr.getRange(), S.Context, ++ArgCount, + Attr.getAttributeSpellingListIndex())); } //===----------------------------------------------------------------------===// Index: test/Sema/xray-log-args-class.cpp =================================================================== --- /dev/null +++ test/Sema/xray-log-args-class.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -verify -fsyntax-only -std=c++11 -x c++ + +class Class { + [[clang::xray_always_instrument, clang::xray_log_args(1)]] void Method(); + [[clang::xray_log_args(-1)]] void Invalid(); // expected-error {{'xray_log_args' attribute parameter 1 is out of bounds}} + [[clang::xray_log_args("invalid")]] void InvalidStringArg(); // expected-error {{'xray_log_args'}} +};