diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index c08bd0c8634a9722d39ce0cd240f368d0acb8d61..e440d58141baab29920cad55dd1a7f7bec06432e 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -3272,7 +3272,8 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
 	break;
 
       /* Otherwise, the types should be pointers.  */
-      if (!TYPE_PTR_OR_PTRMEM_P (type1) || !TYPE_PTR_OR_PTRMEM_P (type2))
+      if (!((TYPE_PTR_OR_PTRMEM_P (type1) || null_ptr_cst_p (args[0]))
+	    && (TYPE_PTR_OR_PTRMEM_P (type2) || null_ptr_cst_p (args[1]))))
 	return;
 
       /* We don't check that the two types are the same; the logic
diff --git a/gcc/testsuite/g++.dg/conversion/op8.C b/gcc/testsuite/g++.dg/conversion/op8.C
new file mode 100644
index 0000000000000000000000000000000000000000..eac958776c9444ed4bc354245c9a0acd86a05acf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/conversion/op8.C
@@ -0,0 +1,75 @@
+// PR c++/118282
+// { dg-do "compile" }
+
+#if __cplusplus >= 201103L
+# include <cstdint> // Only available from c++11 onwards.
+#endif
+
+struct A {
+  explicit A (int);
+  operator void* () const;
+};
+
+struct B {
+  explicit B (int);
+  operator char* () const;
+};
+
+struct C {
+  explicit C (int);
+  operator int () const;
+};
+
+struct BothWays {
+  BothWays (int);
+  operator void*() const;
+};
+
+extern bool my_bool;
+
+void foo (const A& a, const B& b, const C& c, const BothWays& d) {
+  void *res_a_1 = 0	  ? 0 : a;
+  void *res_a_2 = 1	  ? 0 : a;
+  void *res_a_3 = my_bool ? 0 : a;
+  void *res_a_4 = 0	  ? a : 0;
+  void *res_a_5 = 1	  ? a : 0;
+  void *res_a_6 = my_bool ? a : 0;
+
+  void *res_b_1 = 0	  ? 0 : b;
+  void *res_b_2 = 1	  ? 0 : b;
+  void *res_b_3 = my_bool ? 0 : b;
+  void *res_b_4 = 0	  ? b : 0;
+  void *res_b_5 = 1	  ? b : 0;
+  void *res_b_6 = my_bool ? b : 0;
+
+  //
+  // 0 valued constants that are NOT null pointer constants - this worked already.
+  //
+  char zero_char  = 0;
+  void *res_ko1	  = 0	  ? zero_char : a; // { dg-error "different types" }
+
+#if __cplusplus >= 201103L
+  // Those are only available starting with c++11.
+  int8_t zero_i8  = 0;
+  void *res_ko2	  = 0	  ? zero_i8   : a; // { dg-error "different types" "" { target c++11 }  }
+  uintptr_t zerop = 0;
+  void *res_ko3	  = 0	  ? zerop     : a; // { dg-error "different types" "" { target c++11 }  }
+#endif
+
+  // Conversion to integer - this worked already.
+  int res_int	  = 0	  ? 0 : c;
+
+  // Case where one arm is of class type that can be constructed from an
+  // integer and the other arm is a null pointer constant (inspired by
+  // g++.dg/template/cond5.C).
+  0 ? d : 0;
+  0 ? 0 : d;
+}
+
+int main(){
+  A a (5);
+  B b (42);
+  C c (43);
+  BothWays d (1982);
+  foo (a, b, c, d);
+}