This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rGf8a9c55bef38: [clang][Interp] Emit diagnostic when comparing function pointers (authored by tbaeder).
Changed prior to commit: https://reviews.llvm.org/D149154?vs=516790&id=517506#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D149154/new/ https://reviews.llvm.org/D149154 Files: clang/lib/AST/Interp/FunctionPointer.h clang/lib/AST/Interp/Interp.h clang/lib/AST/Interp/Opcodes.td clang/test/AST/Interp/functions.cpp
Index: clang/test/AST/Interp/functions.cpp =================================================================== --- clang/test/AST/Interp/functions.cpp +++ clang/test/AST/Interp/functions.cpp @@ -178,6 +178,31 @@ static_assert(s.fp == nullptr, ""); // zero-initialized function pointer. } +namespace Comparison { + void f(), g(); + constexpr void (*pf)() = &f, (*pg)() = &g; + + constexpr bool u13 = pf < pg; // ref-warning {{ordered comparison of function pointers}} \ + // ref-error {{must be initialized by a constant expression}} \ + // ref-note {{comparison between '&f' and '&g' has unspecified value}} \ + // expected-warning {{ordered comparison of function pointers}} \ + // expected-error {{must be initialized by a constant expression}} \ + // expected-note {{comparison between '&f' and '&g' has unspecified value}} + + constexpr bool u14 = pf < (void(*)())nullptr; // ref-warning {{ordered comparison of function pointers}} \ + // ref-error {{must be initialized by a constant expression}} \ + // ref-note {{comparison between '&f' and 'nullptr' has unspecified value}} \ + // expected-warning {{ordered comparison of function pointers}} \ + // expected-error {{must be initialized by a constant expression}} \ + // expected-note {{comparison between '&f' and 'nullptr' has unspecified value}} + + + + static_assert(pf != pg, ""); + static_assert(pf == &f, ""); + static_assert(pg == &g, ""); +} + } struct F { Index: clang/lib/AST/Interp/Opcodes.td =================================================================== --- clang/lib/AST/Interp/Opcodes.td +++ clang/lib/AST/Interp/Opcodes.td @@ -94,7 +94,7 @@ } def ComparableTypeClass : TypeClass { - let Types = !listconcat(AluTypeClass.Types, [Ptr], [Float]); + let Types = !listconcat(AluTypeClass.Types, [Ptr], [Float], [FnPtr]); } class SingletonTypeClass<Type Ty> : TypeClass { Index: clang/lib/AST/Interp/Interp.h =================================================================== --- clang/lib/AST/Interp/Interp.h +++ clang/lib/AST/Interp/Interp.h @@ -574,6 +574,29 @@ return CmpHelper<T>(S, OpPC, Fn); } +/// Function pointers cannot be compared in an ordered way. +template <> +inline bool CmpHelper<FunctionPointer>(InterpState &S, CodePtr OpPC, + CompareFn Fn) { + const auto &RHS = S.Stk.pop<FunctionPointer>(); + const auto &LHS = S.Stk.pop<FunctionPointer>(); + + const SourceInfo &Loc = S.Current->getSource(OpPC); + S.FFDiag(Loc, diag::note_constexpr_pointer_comparison_unspecified) + << LHS.toDiagnosticString(S.getCtx()) + << RHS.toDiagnosticString(S.getCtx()); + return false; +} + +template <> +inline bool CmpHelperEQ<FunctionPointer>(InterpState &S, CodePtr OpPC, + CompareFn Fn) { + const auto &RHS = S.Stk.pop<FunctionPointer>(); + const auto &LHS = S.Stk.pop<FunctionPointer>(); + S.Stk.push<Boolean>(Boolean::from(Fn(LHS.compare(RHS)))); + return true; +} + template <> inline bool CmpHelper<Pointer>(InterpState &S, CodePtr OpPC, CompareFn Fn) { using BoolT = PrimConv<PT_Bool>::T; Index: clang/lib/AST/Interp/FunctionPointer.h =================================================================== --- clang/lib/AST/Interp/FunctionPointer.h +++ clang/lib/AST/Interp/FunctionPointer.h @@ -8,6 +8,7 @@ #include "clang/AST/APValue.h" namespace clang { +class ASTContext; namespace interp { class FunctionPointer final { @@ -38,6 +39,13 @@ OS << ")"; } + std::string toDiagnosticString(const ASTContext &Ctx) const { + if (!Func) + return "nullptr"; + + return toAPValue().getAsString(Ctx, Func->getDecl()->getType()); + } + ComparisonCategoryResult compare(const FunctionPointer &RHS) const { if (Func == RHS.Func) return ComparisonCategoryResult::Equal;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits