From d9557ee91ddf70e12584f190efb1f1a647f228b7 Mon Sep 17 00:00:00 2001 From: Dean Michael Berris <dberris@google.com> Date: Fri, 16 Jun 2017 03:22:09 +0000 Subject: [PATCH] [XRay][clang] Support capturing the implicit `this` argument to C++ class member functions Summary: Before this change, we couldn't capture the `this` pointer that's implicitly the first argument of class member functions. There are some interesting things we can do with capturing even just this single argument for zero-argument member functions. Reviewers: rnk, pelikan Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D34052 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@305544 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDeclAttr.cpp | 14 ++++++++------ test/Sema/xray-log-args-class.cpp | 7 +++++++ 2 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 test/Sema/xray-log-args-class.cpp diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 6c492fac9eb..b43642f5493 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -313,8 +313,8 @@ static bool checkAttrMutualExclusion(Sema &S, Decl *D, SourceRange Range, /// \returns true if IdxExpr is a valid index. template <typename AttrInfo> static bool checkFunctionOrMethodParameterIndex( - Sema &S, const Decl *D, const AttrInfo& Attr, - unsigned AttrArgNum, const Expr *IdxExpr, uint64_t &Idx) { + Sema &S, const Decl *D, const AttrInfo &Attr, unsigned AttrArgNum, + const Expr *IdxExpr, uint64_t &Idx, bool AllowImplicitThis = false) { assert(isFunctionOrMethodOrBlock(D)); // In C++ the implicit 'this' function parameter also counts. @@ -341,7 +341,7 @@ static bool checkFunctionOrMethodParameterIndex( return false; } Idx--; // Convert to zero-based. - if (HasImplicitThisParam) { + if (HasImplicitThisParam && !AllowImplicitThis) { if (Idx == 0) { S.Diag(getAttrLoc(Attr), diag::err_attribute_invalid_implicit_this_argument) @@ -4604,14 +4604,16 @@ static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D, static void handleXRayLogArgsAttr(Sema &S, Decl *D, const AttributeList &Attr) { uint64_t ArgCount; + if (!checkFunctionOrMethodParameterIndex(S, D, Attr, 1, Attr.getArgAsExpr(0), - ArgCount)) + ArgCount, + true /* AllowImplicitThis*/)) 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())); } //===----------------------------------------------------------------------===// diff --git a/test/Sema/xray-log-args-class.cpp b/test/Sema/xray-log-args-class.cpp new file mode 100644 index 00000000000..10da93f614f --- /dev/null +++ b/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'}} +}; -- GitLab