r174242 - This patch makes "&Cls::purevfn" not an odr use. This isn't what the standard

Richard Smith richard at metafoo.co.uk
Fri Feb 1 16:30:20 PST 2013


On Fri, Feb 1, 2013 at 4:25 PM, Nick Lewycky <nicholas at mxc.ca> wrote:
> Author: nicholas
> Date: Fri Feb  1 18:25:55 2013
> New Revision: 174242
>
> URL: http://llvm.org/viewvc/llvm-project?rev=174242&view=rev
> Log:
> This patch makes "&Cls::purevfn" not an odr use. This isn't what the standard
> says, but that's a defect (to be filed). "Cls::purevfn()" is still an odr use.

FYI, defect has been filed, will be in the pre-Bristol mailing.

> Also fixes a bug that caused us to not mark the function referenced just
> because we didn't want to mark it odr used.
>
> Modified:
>     cfe/trunk/include/clang/Sema/Sema.h
>     cfe/trunk/lib/Sema/SemaExpr.cpp
>     cfe/trunk/lib/Sema/SemaTemplate.cpp
>     cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp
>     cfe/trunk/test/SemaCXX/address-of.cpp
>     cfe/trunk/test/SemaCXX/undefined-internal.cpp
>
> Modified: cfe/trunk/include/clang/Sema/Sema.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=174242&r1=174241&r2=174242&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Sema/Sema.h (original)
> +++ cfe/trunk/include/clang/Sema/Sema.h Fri Feb  1 18:25:55 2013
> @@ -2863,7 +2863,7 @@ public:
>    // for expressions referring to a decl; these exist because odr-use marking
>    // needs to be delayed for some constant variables when we build one of the
>    // named expressions.
> -  void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D);
> +  void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool OdrUse);
>    void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func);
>    void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var);
>    void MarkDeclRefReferenced(DeclRefExpr *E);
>
> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=174242&r1=174241&r2=174242&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Feb  1 18:25:55 2013
> @@ -2025,7 +2025,7 @@ Sema::LookupInObjCMethod(LookupResult &L
>        if (SelfExpr.isInvalid())
>          return ExprError();
>
> -      MarkAnyDeclReferenced(Loc, IV);
> +      MarkAnyDeclReferenced(Loc, IV, true);
>
>        ObjCMethodFamily MF = CurMethod->getMethodFamily();
>        if (MF != OMF_init && MF != OMF_dealloc && MF != OMF_finalize)
> @@ -11152,13 +11152,13 @@ void Sema::MarkVariableReferenced(Source
>  }
>
>  static void MarkExprReferenced(Sema &SemaRef, SourceLocation Loc,
> -                               Decl *D, Expr *E) {
> +                               Decl *D, Expr *E, bool OdrUse) {
>    if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
>      DoMarkVarDeclReferenced(SemaRef, Loc, Var, E);
>      return;
>    }
>
> -  SemaRef.MarkAnyDeclReferenced(Loc, D);
> +  SemaRef.MarkAnyDeclReferenced(Loc, D, OdrUse);
>
>    // If this is a call to a method via a cast, also mark the method in the
>    // derived class used in case codegen can devirtualize the call.
> @@ -11175,12 +11175,19 @@ static void MarkExprReferenced(Sema &Sem
>    CXXMethodDecl *DM = MD->getCorrespondingMethodInClass(MostDerivedClassDecl);
>    if (!DM)
>      return;
> -  SemaRef.MarkAnyDeclReferenced(Loc, DM);
> +  SemaRef.MarkAnyDeclReferenced(Loc, DM, OdrUse);
>  }
>
>  /// \brief Perform reference-marking and odr-use handling for a DeclRefExpr.
>  void Sema::MarkDeclRefReferenced(DeclRefExpr *E) {
> -  MarkExprReferenced(*this, E->getLocation(), E->getDecl(), E);
> +  // TODO: update this with DR# once a defect report is filed.
> +  // C++11 defect. The address of a pure member should not be an ODR use, even
> +  // if it's a qualified reference.
> +  bool OdrUse = true;
> +  if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(E->getDecl()))
> +    if (Method->isPure())
> +      OdrUse = false;
> +  MarkExprReferenced(*this, E->getLocation(), E->getDecl(), E, OdrUse);
>  }
>
>  /// \brief Perform reference-marking and odr-use handling for a MemberExpr.
> @@ -11191,25 +11198,31 @@ void Sema::MarkMemberReferenced(MemberEx
>    //   overload resolution when referred to from a potentially-evaluated
>    //   expression, is odr-used, unless it is a pure virtual function and its
>    //   name is not explicitly qualified.
> +  bool OdrUse = true;
>    if (!E->hasQualifier()) {
>      if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(E->getMemberDecl()))
>        if (Method->isPure())
> -        return;
> +        OdrUse = false;
>    }
> -  MarkExprReferenced(*this, E->getMemberLoc(), E->getMemberDecl(), E);
> +  MarkExprReferenced(*this, E->getMemberLoc(), E->getMemberDecl(), E, OdrUse);
>  }
>
>  /// \brief Perform marking for a reference to an arbitrary declaration.  It
>  /// marks the declaration referenced, and performs odr-use checking for functions
>  /// and variables. This method should not be used when building an normal
>  /// expression which refers to a variable.
> -void Sema::MarkAnyDeclReferenced(SourceLocation Loc, Decl *D) {
> -  if (VarDecl *VD = dyn_cast<VarDecl>(D))
> -    MarkVariableReferenced(Loc, VD);
> -  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
> -    MarkFunctionReferenced(Loc, FD);
> -  else
> -    D->setReferenced();
> +void Sema::MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool OdrUse) {
> +  if (OdrUse) {
> +    if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
> +      MarkVariableReferenced(Loc, VD);
> +      return;
> +    }
> +    if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
> +      MarkFunctionReferenced(Loc, FD);
> +      return;
> +    }
> +  }
> +  D->setReferenced();
>  }
>
>  namespace {
> @@ -11234,7 +11247,7 @@ bool MarkReferencedDecls::TraverseTempla
>    const TemplateArgument &Arg) {
>    if (Arg.getKind() == TemplateArgument::Declaration) {
>      if (Decl *D = Arg.getAsDecl())
> -      S.MarkAnyDeclReferenced(Loc, D);
> +      S.MarkAnyDeclReferenced(Loc, D, true);
>    }
>
>    return Inherited::TraverseTemplateArgument(Arg);
>
> Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=174242&r1=174241&r2=174242&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Fri Feb  1 18:25:55 2013
> @@ -3950,7 +3950,7 @@ CheckTemplateArgumentAddressOfObjectOrFu
>    // Create the template argument.
>    Converted = TemplateArgument(cast<ValueDecl>(Entity->getCanonicalDecl()),
>                                 ParamType->isReferenceType());
> -  S.MarkAnyDeclReferenced(Arg->getLocStart(), Entity);
> +  S.MarkAnyDeclReferenced(Arg->getLocStart(), Entity, false);
>    return false;
>  }
>
>
> Modified: cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp?rev=174242&r1=174241&r2=174242&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp Fri Feb  1 18:25:55 2013
> @@ -844,7 +844,7 @@ ExprResult Sema::ActOnSizeofParameterPac
>      return ExprError();
>    }
>
> -  MarkAnyDeclReferenced(OpLoc, ParameterPack);
> +  MarkAnyDeclReferenced(OpLoc, ParameterPack, true);
>
>    return new (Context) SizeOfPackExpr(Context.getSizeType(), OpLoc,
>                                        ParameterPack, NameLoc, RParenLoc);
>
> Modified: cfe/trunk/test/SemaCXX/address-of.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/address-of.cpp?rev=174242&r1=174241&r2=174242&view=diff
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/address-of.cpp (original)
> +++ cfe/trunk/test/SemaCXX/address-of.cpp Fri Feb  1 18:25:55 2013
> @@ -44,3 +44,11 @@ void PR11066::test() {
>    int (PR11066::*ptr)(int) = & &PR11066::foo; // expected-error{{address expression must be an lvalue or a function designator}}
>  }
>
> +namespace test3 {
> +  // emit no error
> +  template<typename T> struct S {
> +    virtual void f() = 0;
> +  };
> +  template<typename T> void S<T>::f() { T::error; }
> +  void (S<int>::*p)() = &S<int>::f;
> +}
>
> Modified: cfe/trunk/test/SemaCXX/undefined-internal.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/undefined-internal.cpp?rev=174242&r1=174241&r2=174242&view=diff
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/undefined-internal.cpp (original)
> +++ cfe/trunk/test/SemaCXX/undefined-internal.cpp Fri Feb  1 18:25:55 2013
> @@ -212,3 +212,22 @@ namespace test9 {
>      x.X::used(); // expected-note {{used here}}
>    }
>  }
> +
> +namespace test10 {
> +  namespace {
> +    struct X {
> +      virtual void notused() = 0;
> +      virtual void used() = 0; // expected-warning {{function 'test10::<anonymous namespace>::X::used' has internal linkage but is not defined}}
> +
> +      void test() {
> +        notused();
> +        (void)&X::notused;
> +        (this->*&X::notused)();
> +        X::used();  // expected-note {{used here}}
> +      }
> +    };
> +    struct Y : X {
> +      using X::notused;
> +    };
> +  }
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits



More information about the cfe-commits mailing list