[PATCH] D78444: Perform ActOnConversionDeclarator after looking for any virtual functions it overrides

2020-05-13 Thread Ronald Wampler via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG4b53495c4ba2: Perform ActOnConversionDeclarator after 
looking for any virtual functions it… (authored by rdwampler).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78444/new/

https://reviews.llvm.org/D78444

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/conversion-function.cpp


Index: clang/test/SemaCXX/conversion-function.cpp
===
--- clang/test/SemaCXX/conversion-function.cpp
+++ clang/test/SemaCXX/conversion-function.cpp
@@ -62,6 +62,24 @@
   operator const B(); // expected-warning{{conversion function converting 'B' 
to itself will never be used}}
 };
 
+class BaseA {};
+class DerivedA;
+
+class BaseB {
+  virtual operator BaseA &() = 0;
+  virtual operator DerivedA &() = 0;
+};
+
+class DerivedA : public BaseA, BaseB {
+  virtual operator BaseA &();// OK. Overrides BaseB::operatorBaseA&()
+  virtual operator DerivedA &(); // OK. Overrides BaseB::operatorDerivedA&()
+};
+
+class DerivedB : public BaseA {
+  virtual operator DerivedB &(); // expected-warning{{conversion function 
converting 'DerivedB' to itself will never be used}}
+  virtual operator BaseA &();// expected-warning{{conversion function 
converting 'DerivedB' to its base class 'BaseA' will never be used}}
+};
+
 // This used to crash Clang.
 struct Flip;
 struct Flop {
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -10486,15 +10486,12 @@
 
   // Make sure we aren't redeclaring the conversion function.
   QualType ConvType = 
Context.getCanonicalType(Conversion->getConversionType());
-
   // C++ [class.conv.fct]p1:
   //   [...] A conversion function is never used to convert a
   //   (possibly cv-qualified) object to the (possibly cv-qualified)
   //   same object type (or a reference to it), to a (possibly
   //   cv-qualified) base class of that type (or a reference to it),
   //   or to (possibly cv-qualified) void.
-  // FIXME: Suppress this warning if the conversion function ends up being a
-  // virtual function that overrides a virtual function in a base class.
   QualType ClassType
 = Context.getCanonicalType(Context.getTypeDeclType(ClassDecl));
   if (const ReferenceType *ConvTypeRef = ConvType->getAs())
@@ -10502,6 +10499,8 @@
   if (Conversion->getTemplateSpecializationKind() != TSK_Undeclared &&
   Conversion->getTemplateSpecializationKind() != 
TSK_ExplicitSpecialization)
 /* Suppress diagnostics for instantiations. */;
+  else if (Conversion->size_overridden_methods() != 0)
+/* Suppress diagnostics for overriding virtual function in a base class. 
*/;
   else if (ConvType->isRecordType()) {
 ConvType = Context.getCanonicalType(ConvType).getUnqualifiedType();
 if (ConvType == ClassType)
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -10716,9 +10716,6 @@
   return Redeclaration;
 }
   }
-} else if (CXXConversionDecl *Conversion
-   = dyn_cast(NewFD)) {
-  ActOnConversionDeclarator(Conversion);
 } else if (auto *Guide = dyn_cast(NewFD)) {
   if (auto *TD = Guide->getDescribedFunctionTemplate())
 CheckDeductionGuideTemplate(TD);
@@ -10747,6 +10744,9 @@
 checkThisInStaticMemberFunctionType(Method);
 }
 
+if (CXXConversionDecl *Conversion = dyn_cast(NewFD))
+  ActOnConversionDeclarator(Conversion);
+
 // Extra checking for C++ overloaded operators (C++ [over.oper]).
 if (NewFD->isOverloadedOperator() &&
 CheckOverloadedOperatorDeclaration(NewFD)) {


Index: clang/test/SemaCXX/conversion-function.cpp
===
--- clang/test/SemaCXX/conversion-function.cpp
+++ clang/test/SemaCXX/conversion-function.cpp
@@ -62,6 +62,24 @@
   operator const B(); // expected-warning{{conversion function converting 'B' to itself will never be used}}
 };
 
+class BaseA {};
+class DerivedA;
+
+class BaseB {
+  virtual operator BaseA &() = 0;
+  virtual operator DerivedA &() = 0;
+};
+
+class DerivedA : public BaseA, BaseB {
+  virtual operator BaseA &();// OK. Overrides BaseB::operatorBaseA&()
+  virtual operator DerivedA &(); // OK. Overrides BaseB::operatorDerivedA&()
+};
+
+class DerivedB : public BaseA {
+  virtual operator DerivedB &(); // expected-warning{{conversion function converting 'DerivedB' to itself will never be used}}
+  virtual operator BaseA &();// expected-warning{{conversion function converting 'DerivedB' to its base class 'BaseA' will never be used}}
+};
+
 // This used to crash Clang.
 struct Flip;
 struct Flop {
Index: clang/lib/Sema/SemaDeclCXX.cpp

[PATCH] D78444: Perform ActOnConversionDeclarator after looking for any virtual functions it overrides

2020-05-12 Thread Ronald Wampler via Phabricator via cfe-commits
rdwampler updated this revision to Diff 263466.
rdwampler added a comment.

Fixed indentation.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78444/new/

https://reviews.llvm.org/D78444

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/conversion-function.cpp


Index: clang/test/SemaCXX/conversion-function.cpp
===
--- clang/test/SemaCXX/conversion-function.cpp
+++ clang/test/SemaCXX/conversion-function.cpp
@@ -62,6 +62,24 @@
   operator const B(); // expected-warning{{conversion function converting 'B' 
to itself will never be used}}
 };
 
+class BaseA {};
+class DerivedA;
+
+class BaseB {
+  virtual operator BaseA &() = 0;
+  virtual operator DerivedA &() = 0;
+};
+
+class DerivedA : public BaseA, BaseB {
+  virtual operator BaseA &();// OK. Overrides BaseB::operatorBaseA&()
+  virtual operator DerivedA &(); // OK. Overrides BaseB::operatorDerivedA&()
+};
+
+class DerivedB : public BaseA {
+  virtual operator DerivedB &(); // expected-warning{{conversion function 
converting 'DerivedB' to itself will never be used}}
+  virtual operator BaseA &();// expected-warning{{conversion function 
converting 'DerivedB' to its base class 'BaseA' will never be used}}
+};
+
 // This used to crash Clang.
 struct Flip;
 struct Flop {
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -10486,15 +10486,12 @@
 
   // Make sure we aren't redeclaring the conversion function.
   QualType ConvType = 
Context.getCanonicalType(Conversion->getConversionType());
-
   // C++ [class.conv.fct]p1:
   //   [...] A conversion function is never used to convert a
   //   (possibly cv-qualified) object to the (possibly cv-qualified)
   //   same object type (or a reference to it), to a (possibly
   //   cv-qualified) base class of that type (or a reference to it),
   //   or to (possibly cv-qualified) void.
-  // FIXME: Suppress this warning if the conversion function ends up being a
-  // virtual function that overrides a virtual function in a base class.
   QualType ClassType
 = Context.getCanonicalType(Context.getTypeDeclType(ClassDecl));
   if (const ReferenceType *ConvTypeRef = ConvType->getAs())
@@ -10502,6 +10499,8 @@
   if (Conversion->getTemplateSpecializationKind() != TSK_Undeclared &&
   Conversion->getTemplateSpecializationKind() != 
TSK_ExplicitSpecialization)
 /* Suppress diagnostics for instantiations. */;
+  else if (Conversion->size_overridden_methods() != 0)
+/* Suppress diagnostics for overriding virtual function in a base class. 
*/;
   else if (ConvType->isRecordType()) {
 ConvType = Context.getCanonicalType(ConvType).getUnqualifiedType();
 if (ConvType == ClassType)
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -10716,9 +10716,6 @@
   return Redeclaration;
 }
   }
-} else if (CXXConversionDecl *Conversion
-   = dyn_cast(NewFD)) {
-  ActOnConversionDeclarator(Conversion);
 } else if (auto *Guide = dyn_cast(NewFD)) {
   if (auto *TD = Guide->getDescribedFunctionTemplate())
 CheckDeductionGuideTemplate(TD);
@@ -10747,6 +10744,9 @@
 checkThisInStaticMemberFunctionType(Method);
 }
 
+if (CXXConversionDecl *Conversion = dyn_cast(NewFD))
+  ActOnConversionDeclarator(Conversion);
+
 // Extra checking for C++ overloaded operators (C++ [over.oper]).
 if (NewFD->isOverloadedOperator() &&
 CheckOverloadedOperatorDeclaration(NewFD)) {


Index: clang/test/SemaCXX/conversion-function.cpp
===
--- clang/test/SemaCXX/conversion-function.cpp
+++ clang/test/SemaCXX/conversion-function.cpp
@@ -62,6 +62,24 @@
   operator const B(); // expected-warning{{conversion function converting 'B' to itself will never be used}}
 };
 
+class BaseA {};
+class DerivedA;
+
+class BaseB {
+  virtual operator BaseA &() = 0;
+  virtual operator DerivedA &() = 0;
+};
+
+class DerivedA : public BaseA, BaseB {
+  virtual operator BaseA &();// OK. Overrides BaseB::operatorBaseA&()
+  virtual operator DerivedA &(); // OK. Overrides BaseB::operatorDerivedA&()
+};
+
+class DerivedB : public BaseA {
+  virtual operator DerivedB &(); // expected-warning{{conversion function converting 'DerivedB' to itself will never be used}}
+  virtual operator BaseA &();// expected-warning{{conversion function converting 'DerivedB' to its base class 'BaseA' will never be used}}
+};
+
 // This used to crash Clang.
 struct Flip;
 struct Flop {
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -10486,15 +1

[PATCH] D78444: Perform ActOnConversionDeclarator after looking for any virtual functions it overrides

2020-05-11 Thread John McCall via Phabricator via cfe-commits
rjmccall added a comment.

LGTM with a minor fix.




Comment at: clang/lib/Sema/SemaDecl.cpp:10745
+if (CXXConversionDecl *Conversion = dyn_cast(NewFD))
+  ActOnConversionDeclarator(Conversion);
 

Indentation is off.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78444/new/

https://reviews.llvm.org/D78444



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D78444: Perform ActOnConversionDeclarator after looking for any virtual functions it overrides

2020-05-05 Thread Ronald Wampler via Phabricator via cfe-commits
rdwampler added a comment.

Ping.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78444/new/

https://reviews.llvm.org/D78444



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D78444: Perform ActOnConversionDeclarator after looking for any virtual functions it overrides

2020-04-19 Thread Ronald Wampler via Phabricator via cfe-commits
rdwampler updated this revision to Diff 258613.
rdwampler added a comment.

changed to check it overrides a virtual function in a base class and not just 
virtual.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78444/new/

https://reviews.llvm.org/D78444

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/conversion-function.cpp


Index: clang/test/SemaCXX/conversion-function.cpp
===
--- clang/test/SemaCXX/conversion-function.cpp
+++ clang/test/SemaCXX/conversion-function.cpp
@@ -62,6 +62,24 @@
   operator const B(); // expected-warning{{conversion function converting 'B' 
to itself will never be used}}
 };
 
+class BaseA { };
+class DerivedA;
+
+class BaseB {
+virtual operator BaseA&() = 0;
+virtual operator DerivedA&() = 0;
+};
+
+class DerivedA : public BaseA, BaseB {
+virtual operator BaseA&(); // OK. Overrides BaseB::operatorBaseA&()
+virtual operator DerivedA&(); // OK. Overrides BaseB::operatorDerivedA&()
+};
+
+class DerivedB : public BaseA {
+virtual operator DerivedB&(); // expected-warning{{conversion function 
converting 'DerivedB' to itself will never be used}}
+virtual operator BaseA&(); // expected-warning{{conversion function 
converting 'DerivedB' to its base class 'BaseA' will never be used}}
+};
+
 // This used to crash Clang.
 struct Flip;
 struct Flop {
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -10486,15 +10486,12 @@
 
   // Make sure we aren't redeclaring the conversion function.
   QualType ConvType = 
Context.getCanonicalType(Conversion->getConversionType());
-
   // C++ [class.conv.fct]p1:
   //   [...] A conversion function is never used to convert a
   //   (possibly cv-qualified) object to the (possibly cv-qualified)
   //   same object type (or a reference to it), to a (possibly
   //   cv-qualified) base class of that type (or a reference to it),
   //   or to (possibly cv-qualified) void.
-  // FIXME: Suppress this warning if the conversion function ends up being a
-  // virtual function that overrides a virtual function in a base class.
   QualType ClassType
 = Context.getCanonicalType(Context.getTypeDeclType(ClassDecl));
   if (const ReferenceType *ConvTypeRef = ConvType->getAs())
@@ -10502,6 +10499,8 @@
   if (Conversion->getTemplateSpecializationKind() != TSK_Undeclared &&
   Conversion->getTemplateSpecializationKind() != 
TSK_ExplicitSpecialization)
 /* Suppress diagnostics for instantiations. */;
+  else if(Conversion->size_overridden_methods() != 0)
+/* Suppress diagnostics for overriding virtual function in a base class. 
*/;
   else if (ConvType->isRecordType()) {
 ConvType = Context.getCanonicalType(ConvType).getUnqualifiedType();
 if (ConvType == ClassType)
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -10713,9 +10713,6 @@
   return Redeclaration;
 }
   }
-} else if (CXXConversionDecl *Conversion
-   = dyn_cast(NewFD)) {
-  ActOnConversionDeclarator(Conversion);
 } else if (auto *Guide = dyn_cast(NewFD)) {
   if (auto *TD = Guide->getDescribedFunctionTemplate())
 CheckDeductionGuideTemplate(TD);
@@ -10743,6 +10740,9 @@
   if (Method->isStatic())
 checkThisInStaticMemberFunctionType(Method);
 }
+
+if (CXXConversionDecl *Conversion = dyn_cast(NewFD))
+  ActOnConversionDeclarator(Conversion);
 
 // Extra checking for C++ overloaded operators (C++ [over.oper]).
 if (NewFD->isOverloadedOperator() &&


Index: clang/test/SemaCXX/conversion-function.cpp
===
--- clang/test/SemaCXX/conversion-function.cpp
+++ clang/test/SemaCXX/conversion-function.cpp
@@ -62,6 +62,24 @@
   operator const B(); // expected-warning{{conversion function converting 'B' to itself will never be used}}
 };
 
+class BaseA { };
+class DerivedA;
+
+class BaseB {
+virtual operator BaseA&() = 0;
+virtual operator DerivedA&() = 0;
+};
+
+class DerivedA : public BaseA, BaseB {
+virtual operator BaseA&(); // OK. Overrides BaseB::operatorBaseA&()
+virtual operator DerivedA&(); // OK. Overrides BaseB::operatorDerivedA&()
+};
+
+class DerivedB : public BaseA {
+virtual operator DerivedB&(); // expected-warning{{conversion function converting 'DerivedB' to itself will never be used}}
+virtual operator BaseA&(); // expected-warning{{conversion function converting 'DerivedB' to its base class 'BaseA' will never be used}}
+};
+
 // This used to crash Clang.
 struct Flip;
 struct Flop {
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX

[PATCH] D78444: Perform ActOnConversionDeclarator after looking for any virtual functions it overrides

2020-04-18 Thread Ronald Wampler via Phabricator via cfe-commits
rdwampler created this revision.
rdwampler added reviewers: saar.raz, aaron.ballman, doug.gregor, rsmith.
rdwampler added a project: clang.
Herald added subscribers: cfe-commits, dexonsmith.

This allows for suppressing warnings about the conversion function never being 
called if it overrides a virtual function in a base class.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D78444

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/conversion-function.cpp


Index: clang/test/SemaCXX/conversion-function.cpp
===
--- clang/test/SemaCXX/conversion-function.cpp
+++ clang/test/SemaCXX/conversion-function.cpp
@@ -62,6 +62,27 @@
   operator const B(); // expected-warning{{conversion function converting 'B' 
to itself will never be used}}
 };
 
+class DerivedB;
+
+class BaseA {
+public:
+  virtual operator BaseA&() = 0; //OK. Virtual function 
+  virtual operator DerivedB&() = 0; //OK. Virtual function
+  virtual operator const void() = 0; //OK. Virtual function
+};
+
+class DerivedB : public BaseA {
+#if __cplusplus >= 201103L
+operator BaseA&() override; //OK. Overrides virtual function in BaseA
+operator DerivedB&() override; //OK. Overrides virtual function BaseA
+operator const void() override; //OK. Overrides virtual function BaseA
+#else
+virtual operator BaseA&(); //OK. Overrides virtual function in BaseA
+virtual operator DerivedB&(); //OK. Overrides virtual function BaseA
+virtual operator const void(); //OK. Overrides virtual function BaseA
+#endif
+};
+
 // This used to crash Clang.
 struct Flip;
 struct Flop {
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -10486,15 +10486,12 @@
 
   // Make sure we aren't redeclaring the conversion function.
   QualType ConvType = 
Context.getCanonicalType(Conversion->getConversionType());
-
   // C++ [class.conv.fct]p1:
   //   [...] A conversion function is never used to convert a
   //   (possibly cv-qualified) object to the (possibly cv-qualified)
   //   same object type (or a reference to it), to a (possibly
   //   cv-qualified) base class of that type (or a reference to it),
   //   or to (possibly cv-qualified) void.
-  // FIXME: Suppress this warning if the conversion function ends up being a
-  // virtual function that overrides a virtual function in a base class.
   QualType ClassType
 = Context.getCanonicalType(Context.getTypeDeclType(ClassDecl));
   if (const ReferenceType *ConvTypeRef = ConvType->getAs())
@@ -10502,6 +10499,8 @@
   if (Conversion->getTemplateSpecializationKind() != TSK_Undeclared &&
   Conversion->getTemplateSpecializationKind() != 
TSK_ExplicitSpecialization)
 /* Suppress diagnostics for instantiations. */;
+  else if(Conversion->isVirtual())
+/*Suppress diagnostics if the function is virtual*/;
   else if (ConvType->isRecordType()) {
 ConvType = Context.getCanonicalType(ConvType).getUnqualifiedType();
 if (ConvType == ClassType)
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -10713,9 +10713,6 @@
   return Redeclaration;
 }
   }
-} else if (CXXConversionDecl *Conversion
-   = dyn_cast(NewFD)) {
-  ActOnConversionDeclarator(Conversion);
 } else if (auto *Guide = dyn_cast(NewFD)) {
   if (auto *TD = Guide->getDescribedFunctionTemplate())
 CheckDeductionGuideTemplate(TD);
@@ -10743,6 +10740,9 @@
   if (Method->isStatic())
 checkThisInStaticMemberFunctionType(Method);
 }
+
+if (CXXConversionDecl *Conversion = dyn_cast(NewFD))
+  ActOnConversionDeclarator(Conversion);
 
 // Extra checking for C++ overloaded operators (C++ [over.oper]).
 if (NewFD->isOverloadedOperator() &&


Index: clang/test/SemaCXX/conversion-function.cpp
===
--- clang/test/SemaCXX/conversion-function.cpp
+++ clang/test/SemaCXX/conversion-function.cpp
@@ -62,6 +62,27 @@
   operator const B(); // expected-warning{{conversion function converting 'B' to itself will never be used}}
 };
 
+class DerivedB;
+
+class BaseA {
+public:
+  virtual operator BaseA&() = 0; //OK. Virtual function 
+  virtual operator DerivedB&() = 0; //OK. Virtual function
+  virtual operator const void() = 0; //OK. Virtual function
+};
+
+class DerivedB : public BaseA {
+#if __cplusplus >= 201103L
+operator BaseA&() override; //OK. Overrides virtual function in BaseA
+operator DerivedB&() override; //OK. Overrides virtual function BaseA
+operator const void() override; //OK. Overrides virtual function BaseA
+#else
+virtual operator BaseA&(); //OK. Overrides virtual function in BaseA
+virtual operator Derive