diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 2f14e5c..6349259 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2017-11-08  Pedro Alves  <palves@redhat.com>
+
+	* gdb.gdb/complaints.exp (test_initial_complaints)
+	(test_serial_complaints, test_short_complaints): Call
+	complaint_internal instead of complaint.
+
 2017-11-08  Djordje Todorovic  <djordje.todorovic@rt-rk.com>
 
 	* gdb.threads/tls-core.c: New file.
diff --git a/gdb/complaints.c b/gdb/complaints.c
index 58b6b7b..8fd2f2b 100644
--- a/gdb/complaints.c
+++ b/gdb/complaints.c
@@ -148,7 +148,7 @@ find_complaint (struct complaints *complaints, const char *file,
    before we stop whining about it?  Default is no whining at all,
    since so many systems have ill-constructed symbol files.  */
 
-static int stop_whining = 0;
+int stop_whining = 0;
 
 /* Print a complaint, and link the complaint block into a chain for
    later handling.  */
@@ -236,7 +236,7 @@ vcomplaint (struct complaints **c, const char *file,
 }
 
 void
-complaint (struct complaints **complaints, const char *fmt, ...)
+complaint_internal (struct complaints **complaints, const char *fmt, ...)
 {
   va_list args;
 
diff --git a/gdb/complaints.h b/gdb/complaints.h
index 54c2b18..62885e9 100644
--- a/gdb/complaints.h
+++ b/gdb/complaints.h
@@ -28,10 +28,25 @@ struct complaints;
 /* Predefined categories.  */
 extern struct complaints *symfile_complaints;
 
-/* Register a complaint.  */
-extern void complaint (struct complaints **complaints,
-		       const char *fmt,
-		       ...) ATTRIBUTE_PRINTF (2, 3);
+/* Helper for complaint.  */
+extern void complaint_internal (struct complaints **complaints,
+				const char *fmt, ...)
+  ATTRIBUTE_PRINTF (2, 3);
+
+/* Register a complaint.  This is a macro around complaint_internal to
+   avoid computing complaint's arguments when complaints are disabled.
+   Running FMT via gettext [i.e., _(FMT)] can be quite expensive, for
+   example.  */
+#define complaint(COMPLAINTS, FMT, ...)				\
+  do								\
+    {								\
+      extern int stop_whining;					\
+								\
+      if (stop_whining > 0)					\
+	complaint_internal (COMPLAINTS, FMT, ##__VA_ARGS__);	\
+    }								\
+  while (0)
+
 extern void internal_complaint (struct complaints **complaints,
 				const char *file, int line,
 				const char *fmt,
diff --git a/gdb/testsuite/gdb.gdb/complaints.exp b/gdb/testsuite/gdb.gdb/complaints.exp
index c33fb6e..0b03205 100644
--- a/gdb/testsuite/gdb.gdb/complaints.exp
+++ b/gdb/testsuite/gdb.gdb/complaints.exp
@@ -58,16 +58,18 @@ proc test_initial_complaints { } {
     gdb_test "set stop_whining = 2"
 
     # Prime the system
-    gdb_test_stdio "call complaint (&symfile_complaints, \"Register a complaint\")" \
-	    "During symbol reading, Register a complaint."
+    gdb_test_stdio \
+	"call complaint_internal (&symfile_complaints, \"Register a complaint\")" \
+	"During symbol reading, Register a complaint."
 
     # Check that the complaint was inserted and where
     gdb_test "print symfile_complaints->root->fmt" \
 	    ".\[0-9\]+ =.*\"Register a complaint\""
 
     # Re-issue the first message #1
-    gdb_test_stdio "call complaint (&symfile_complaints, symfile_complaints->root->fmt)" \
-	    "During symbol reading, Register a complaint."
+    gdb_test_stdio \
+	"call complaint_internal (&symfile_complaints, symfile_complaints->root->fmt)" \
+	"During symbol reading, Register a complaint."
 
     # Check that there is only one thing in the list.  How the boolean
     # result is output depends on whether GDB is built as a C or C++
@@ -76,8 +78,9 @@ proc test_initial_complaints { } {
 	    ".\[0-9\]+ = \(1|true\)" "list has one entry"
 
     # Add a second complaint, expect it
-    gdb_test_stdio "call complaint (&symfile_complaints, \"Testing! Testing! Testing!\")" \
-	    "During symbol reading, Testing. Testing. Testing.."
+    gdb_test_stdio \
+	"call complaint_internal (&symfile_complaints, \"Testing! Testing! Testing!\")" \
+	"During symbol reading, Testing. Testing. Testing.."
 
     return 0
 }
@@ -86,12 +89,14 @@ proc test_serial_complaints { } {
     gdb_test_exact "call clear_complaints (&symfile_complaints, 1, 0)" "" "serial start"
 
     # Prime the system
-    test_complaint "call complaint (&symfile_complaints, \"serial line 1\")" \
+    test_complaint \
+	"call complaint_internal (&symfile_complaints, \"serial line 1\")" \
 	"During symbol reading...serial line 1..." \
 	"serial line 1"
 
     # Add a second complaint, expect it
-    test_complaint "call complaint (&symfile_complaints, \"serial line 2\")" \
+    test_complaint \
+	"call complaint_internal (&symfile_complaints, \"serial line 2\")" \
 	"serial line 2..." \
 	"serial line 2"
 
@@ -109,12 +114,14 @@ proc test_short_complaints { } {
     gdb_test_exact "call clear_complaints (&symfile_complaints, 1, 1)" "" "short start"
 
     # Prime the system
-    test_complaint "call complaint (&symfile_complaints, \"short line 1\")" \
+    test_complaint \
+	"call complaint_internal (&symfile_complaints, \"short line 1\")" \
 	"short line 1..." \
 	"short line 1"
 
     # Add a second complaint, expect it
-    test_complaint "call complaint (&symfile_complaints, \"short line 2\")" \
+    test_complaint \
+	"call complaint_internal (&symfile_complaints, \"short line 2\")" \
 	"short line 2..." \
 	"short line 2"
 
