Merge pull request #10739 from jrose-apple/4.0-conditional-surrender

[4.0] Do stricter checking of -D command line arguments
diff --git a/include/swift/AST/DiagnosticsFrontend.def b/include/swift/AST/DiagnosticsFrontend.def
index de704ff..e098c22 100644
--- a/include/swift/AST/DiagnosticsFrontend.def
+++ b/include/swift/AST/DiagnosticsFrontend.def
@@ -194,6 +194,14 @@
       "symbol '%0' (%1) is in generated IR file, but not in TBD file",
       (StringRef, StringRef))
 
+ERROR(invalid_conditional_compilation_flag,none,
+      "conditional compilation flags must be valid Swift identifiers (rather than '%0')",
+      (StringRef))
+
+WARNING(cannot_assign_value_to_conditional_compilation_flag,none,
+        "conditional compilation flags do not have values in Swift; they are "
+        "either present or absent (rather than '%0')", (StringRef))
+
 #ifndef DIAG_NO_UNDEF
 # if defined(DIAG)
 #  undef DIAG
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index e8c8f7c..42a4640 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -161,7 +161,7 @@
     diags.diagnose(SourceLoc(), diag::error_conflicting_options,
                    "-warnings-as-errors", "-suppress-warnings");
   }
-  
+
   // Check for missing debug option when verifying debug info.
   if (Args.hasArg(options::OPT_verify_debug_info)) {
     bool hasDebugOption = true;
@@ -172,6 +172,18 @@
       diags.diagnose(SourceLoc(),
                      diag::verify_debug_info_requires_debug_option);
   }
+
+  for (const Arg *A : make_range(Args.filtered_begin(options::OPT_D),
+                                 Args.filtered_end())) {
+    StringRef name = A->getValue();
+    if (name.find('=') != StringRef::npos)
+      diags.diagnose(SourceLoc(),
+                     diag::cannot_assign_value_to_conditional_compilation_flag,
+                     name);
+    else if (!Lexer::isIdentifier(name))
+      diags.diagnose(SourceLoc(), diag::invalid_conditional_compilation_flag,
+                     name);
+  }
 }
 
 /// Creates an appropriate ToolChain for a given driver and target triple.
diff --git a/test/Driver/options-repl.swift b/test/Driver/options-repl.swift
index 7967fdb..d980ae8 100644
--- a/test/Driver/options-repl.swift
+++ b/test/Driver/options-repl.swift
@@ -16,7 +16,7 @@
 
 
 // RUN: %swift_driver -lldb-repl -### | %FileCheck -check-prefix=LLDB %s
-// RUN: %swift_driver -lldb-repl -DA,B,C -DD -L /path/to/libraries -L /path/to/more/libraries -F /path/to/frameworks -lsomelib -framework SomeFramework -sdk / -I "this folder" -module-name Test -target %target-triple -### | %FileCheck -check-prefix=LLDB-OPTS %s
+// RUN: %swift_driver -lldb-repl -D A -DB -D C -DD -L /path/to/libraries -L /path/to/more/libraries -F /path/to/frameworks -lsomelib -framework SomeFramework -sdk / -I "this folder" -module-name Test -target %target-triple -### | %FileCheck -check-prefix=LLDB-OPTS %s
 
 // LLDB: lldb{{"?}} {{"?}}--repl=
 // LLDB-NOT: -module-name
@@ -24,7 +24,7 @@
 
 // LLDB-OPTS: lldb{{"?}} "--repl=
 // LLDB-OPTS-DAG: -target {{[^ ]+}}
-// LLDB-OPTS-DAG: -D A,B,C -D D
+// LLDB-OPTS-DAG: -D A -D B -D C -D D
 // LLDB-OPTS-DAG: -sdk /
 // LLDB-OPTS-DAG: -L /path/to/libraries
 // LLDB-OPTS-DAG: -L /path/to/more/libraries
diff --git a/test/Frontend/unknown-arguments.swift b/test/Frontend/unknown-arguments.swift
index d80a2a7..e8f8553 100644
--- a/test/Frontend/unknown-arguments.swift
+++ b/test/Frontend/unknown-arguments.swift
@@ -6,3 +6,9 @@
 // RUN: not %swiftc_driver -c %s -o %t.o -Xfrontend -fake-frontend-arg -Xfrontend fakevalue 2>&1 | %FileCheck -check-prefix=XFRONTEND %s
 
 // XFRONTEND: <unknown>:0: error: unknown argument: '-fake-frontend-arg'
+
+// RUN: not %swiftc_driver -D Correct -DAlsoCorrect -D@#%! -D Swift=Cool -D-D -c %s -o %t.o 2>&1 | %FileCheck -check-prefix=INVALID-COND %s
+// INVALID-COND: <unknown>:0: error: conditional compilation flags must be valid Swift identifiers (rather than '@#%!')
+// INVALID-COND-NEXT: <unknown>:0: warning: conditional compilation flags do not have values in Swift; they are either present or absent (rather than 'Swift=Cool')
+// INVALID-COND-NEXT: <unknown>:0: error: conditional compilation flags must be valid Swift identifiers (rather than '-D')
+