@@ -979,20 +979,6 @@ bool CmpHelperEQ(InterpState &S, CodePtr OpPC, CompareFn Fn) {
979979 return CmpHelper<T>(S, OpPC, Fn);
980980}
981981
982- // / Function pointers cannot be compared in an ordered way.
983- template <>
984- inline bool CmpHelper<FunctionPointer>(InterpState &S, CodePtr OpPC,
985- CompareFn Fn) {
986- const auto &RHS = S.Stk .pop <FunctionPointer>();
987- const auto &LHS = S.Stk .pop <FunctionPointer>();
988-
989- const SourceInfo &Loc = S.Current ->getSource (OpPC);
990- S.FFDiag (Loc, diag::note_constexpr_pointer_comparison_unspecified)
991- << LHS.toDiagnosticString (S.getASTContext ())
992- << RHS.toDiagnosticString (S.getASTContext ());
993- return false ;
994- }
995-
996982template <>
997983inline bool CmpHelperEQ<FunctionPointer>(InterpState &S, CodePtr OpPC,
998984 CompareFn Fn) {
@@ -1019,18 +1005,27 @@ inline bool CmpHelper<Pointer>(InterpState &S, CodePtr OpPC, CompareFn Fn) {
10191005 const Pointer &RHS = S.Stk .pop <Pointer>();
10201006 const Pointer &LHS = S.Stk .pop <Pointer>();
10211007
1008+ // Function pointers cannot be compared in an ordered way.
1009+ if (LHS.isFunctionPointer () || RHS.isFunctionPointer ()) {
1010+ const SourceInfo &Loc = S.Current ->getSource (OpPC);
1011+ S.FFDiag (Loc, diag::note_constexpr_pointer_comparison_unspecified)
1012+ << LHS.toDiagnosticString (S.getASTContext ())
1013+ << RHS.toDiagnosticString (S.getASTContext ());
1014+ return false ;
1015+ }
1016+
10221017 if (!Pointer::hasSameBase (LHS, RHS)) {
10231018 const SourceInfo &Loc = S.Current ->getSource (OpPC);
10241019 S.FFDiag (Loc, diag::note_constexpr_pointer_comparison_unspecified)
10251020 << LHS.toDiagnosticString (S.getASTContext ())
10261021 << RHS.toDiagnosticString (S.getASTContext ());
10271022 return false ;
1028- } else {
1029- unsigned VL = LHS.getByteOffset ();
1030- unsigned VR = RHS.getByteOffset ();
1031- S.Stk .push <BoolT>(BoolT::from (Fn (Compare (VL, VR))));
1032- return true ;
10331023 }
1024+
1025+ unsigned VL = LHS.getByteOffset ();
1026+ unsigned VR = RHS.getByteOffset ();
1027+ S.Stk .push <BoolT>(BoolT::from (Fn (Compare (VL, VR))));
1028+ return true ;
10341029}
10351030
10361031static inline bool IsOpaqueConstantCall (const CallExpr *E) {
@@ -1069,6 +1064,12 @@ inline bool CmpHelperEQ<Pointer>(InterpState &S, CodePtr OpPC, CompareFn Fn) {
10691064 return false ;
10701065 }
10711066
1067+ if (LHS.isFunctionPointer () && RHS.isFunctionPointer ()) {
1068+ S.Stk .push <BoolT>(BoolT::from (Fn (Compare (LHS.getIntegerRepresentation (),
1069+ RHS.getIntegerRepresentation ()))));
1070+ return true ;
1071+ }
1072+
10721073 if (Pointer::hasSameBase (LHS, RHS)) {
10731074 if (LHS.inUnion () && RHS.inUnion ()) {
10741075 // If the pointers point into a union, things are a little more
@@ -2787,7 +2788,7 @@ inline bool ArrayDecay(InterpState &S, CodePtr OpPC) {
27872788
27882789inline bool GetFnPtr (InterpState &S, CodePtr OpPC, const Function *Func) {
27892790 assert (Func);
2790- S.Stk .push <FunctionPointer >(Func);
2791+ S.Stk .push <Pointer >(Func);
27912792 return true ;
27922793}
27932794
@@ -2822,7 +2823,7 @@ inline bool GetMemberPtrDecl(InterpState &S, CodePtr OpPC) {
28222823 const auto *FD = cast<FunctionDecl>(MP.getDecl ());
28232824 const auto *Func = S.getContext ().getOrCreateFunction (FD);
28242825
2825- S.Stk .push <FunctionPointer >(Func);
2826+ S.Stk .push <Pointer >(Func);
28262827 return true ;
28272828}
28282829
0 commit comments