<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Oops, the build log was too big to attach. Resending with just the bot link, then:</div><div class=""><a href="http://lab.llvm.org:8080/green/view/Experimental/job/clang-stage2-coverage-R/2193/consoleText" class="">http://lab.llvm.org:8080/green/view/Experimental/job/clang-stage2-coverage-R/2193/consoleText</a></div><div class=""><br class=""></div><div class="">vedant</div><br class=""><div><blockquote type="cite" class=""><div class="">On Jan 3, 2018, at 11:09 AM, Vedant Kumar <<a href="mailto:vsk@apple.com" class="">vsk@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi Richard,<div class=""><br class=""></div><div class="">This commit is causing an unexpected build failure in the stage2 modules-enabled coverage bot. I've attached the build log. Here's the error:</div><div class=""><br class=""></div><div class=""><pre style="word-wrap: break-word; white-space: pre-wrap;" class="">[3685/3899] /Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/host-compiler/bin/clang++   -DGTEST_HAS_RTTI=0 -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Itools/lld/COFF -I/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/COFF -I/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/include -Itools/lld/include -I/usr/include/libxml2 -Iinclude -I/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -std=c++11 -fmodules -fmodules-cache-path=/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/clang-build/module.cache -fcxx-modules -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wcovered-switch-default -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wstring-conversion -fcolor-diagnostics -fprofile-instr-generate='/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/clang-build/profiles/%6m.profraw' -fcoverage-mapping -O3 -DNDEBUG    -fno-exceptions -fno-rtti -MMD -MT tools/lld/COFF/CMakeFiles/lldCOFF.dir/PDB.cpp.o -MF tools/lld/COFF/CMakeFiles/lldCOFF.dir/PDB.cpp.o.d -o tools/lld/COFF/CMakeFiles/lldCOFF.dir/PDB.cpp.o -c /Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/COFF/PDB.cpp
FAILED: tools/lld/COFF/CMakeFiles/lldCOFF.dir/PDB.cpp.o 
/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/host-compiler/bin/clang++   -DGTEST_HAS_RTTI=0 -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Itools/lld/COFF -I/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/COFF -I/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/include -Itools/lld/include -I/usr/include/libxml2 -Iinclude -I/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -std=c++11 -fmodules -fmodules-cache-path=/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/clang-build/module.cache -fcxx-modules -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wcovered-switch-default -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wstring-conversion -fcolor-diagnostics -fprofile-instr-generate='/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/clang-build/profiles/%6m.profraw' -fcoverage-mapping -O3 -DNDEBUG    -fno-exceptions -fno-rtti -MMD -MT tools/lld/COFF/CMakeFiles/lldCOFF.dir/PDB.cpp.o -MF tools/lld/COFF/CMakeFiles/lldCOFF.dir/PDB.cpp.o.d -o tools/lld/COFF/CMakeFiles/lldCOFF.dir/PDB.cpp.o -c /Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/COFF/PDB.cpp
In module 'std' imported from /Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/COFF/Config.h:16:
/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/host-compiler/include/c++/v1/list:389:10: error: 'std::__1::operator==' has different definitions in different modules; definition in module 'std.list' first difference is function body
    bool operator==(const __list_iterator& __x, const __list_iterator& __y)
    ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/host-compiler/include/c++/v1/list:389:10: note: but in 'std.list' found a different body
    bool operator==(const __list_iterator& __x, const __list_iterator& __y)
    ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/host-compiler/include/c++/v1/list:394:11: error: 'std::__1::operator!=' has different definitions in different modules; definition in module 'std.list' first difference is function body
     bool operator!=(const __list_iterator& __x, const __list_iterator& __y)
     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/host-compiler/include/c++/v1/list:394:11: note: but in 'std.list' found a different body
     bool operator!=(const __list_iterator& __x, const __list_iterator& __y)
     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 errors generated.</pre><div class="">I'm not sure how to act on this, because it looks like the error is saying that a definition in 'std.list' is incompatible with itself.</div></div><div class=""><br class=""></div><div class="">I've temporarily disabled building with modules enabled on the bot. Could you take a look?</div><div class=""><br class=""></div><div class="">thanks,</div><div class="">vedant</div><div class=""><br class=""></div><div class=""><a href="http://lab.llvm.org:8080/green/view/Experimental/job/clang-stage2-coverage-R/2193" class="">http://lab.llvm.org:8080/green/view/Experimental/job/clang-stage2-coverage-R/2193</a></div><div class=""><br class=""></div><div class=""></div></div><span id="cid:A9C968BE-334D-4AE4-B4E0-2D3EEE7AB3BD@apple.com"><coverage-build-log.txt></span><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Dec 22, 2017, at 4:41 PM, Richard Trieu via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">Author: rtrieu<br class="">Date: Fri Dec 22 16:41:01 2017<br class="">New Revision: 321395<br class=""><br class="">URL: <a href="http://llvm.org/viewvc/llvm-project?rev=321395&view=rev" class="">http://llvm.org/viewvc/llvm-project?rev=321395&view=rev</a><br class="">Log:<br class="">[ODRHash] Support ODR violation detection in functions.<br class=""><br class="">Extend the hashing to functions, which allows detection of function definition<br class="">mismatches across modules.  This is a re-commit of r320230.<br class=""><br class="">Modified:<br class="">    cfe/trunk/include/clang/AST/Decl.h<br class="">    cfe/trunk/include/clang/AST/ODRHash.h<br class="">    cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td<br class="">    cfe/trunk/include/clang/Serialization/ASTReader.h<br class="">    cfe/trunk/lib/AST/Decl.cpp<br class="">    cfe/trunk/lib/AST/ODRHash.cpp<br class="">    cfe/trunk/lib/Serialization/ASTReader.cpp<br class="">    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp<br class="">    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp<br class="">    cfe/trunk/test/Modules/odr_hash.cpp<br class=""><br class="">Modified: cfe/trunk/include/clang/AST/Decl.h<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=321395&r1=321394&r2=321395&view=diff" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=321395&r1=321394&r2=321395&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/AST/Decl.h (original)<br class="">+++ cfe/trunk/include/clang/AST/Decl.h Fri Dec 22 16:41:01 2017<br class="">@@ -1759,6 +1759,11 @@ protected:<br class="">   unsigned IsCopyDeductionCandidate : 1;<br class=""><br class=""> private:<br class="">+<br class="">+  /// Store the ODRHash after first calculation.<br class="">+  unsigned HasODRHash : 1;<br class="">+  unsigned ODRHash;<br class="">+<br class="">   /// \brief End part of this FunctionDecl's source range.<br class="">   ///<br class="">   /// We could compute the full range in getSourceRange(). However, when we're<br class="">@@ -1841,8 +1846,9 @@ protected:<br class="">         IsExplicitlyDefaulted(false), HasImplicitReturnZero(false),<br class="">         IsLateTemplateParsed(false), IsConstexpr(isConstexprSpecified),<br class="">         InstantiationIsPending(false), UsesSEHTry(false), HasSkippedBody(false),<br class="">-        WillHaveBody(false), IsCopyDeductionCandidate(false),<br class="">-        EndRangeLoc(NameInfo.getEndLoc()), DNLoc(NameInfo.getInfo()) {}<br class="">+        WillHaveBody(false), IsCopyDeductionCandidate(false), HasODRHash(false),<br class="">+        ODRHash(0), EndRangeLoc(NameInfo.getEndLoc()),<br class="">+        DNLoc(NameInfo.getInfo()) {}<br class=""><br class="">   using redeclarable_base = Redeclarable<FunctionDecl>;<br class=""><br class="">@@ -2439,6 +2445,10 @@ public:<br class="">   /// returns 0.<br class="">   unsigned getMemoryFunctionKind() const;<br class=""><br class="">+  /// \brief Returns ODRHash of the function.  This value is calculated and<br class="">+  /// stored on first call, then the stored value returned on the other calls.<br class="">+  unsigned getODRHash();<br class="">+<br class="">   // Implement isa/cast/dyncast/etc.<br class="">   static bool classof(const Decl *D) { return classofKind(D->getKind()); }<br class="">   static bool classofKind(Kind K) {<br class=""><br class="">Modified: cfe/trunk/include/clang/AST/ODRHash.h<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ODRHash.h?rev=321395&r1=321394&r2=321395&view=diff" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ODRHash.h?rev=321395&r1=321394&r2=321395&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/AST/ODRHash.h (original)<br class="">+++ cfe/trunk/include/clang/AST/ODRHash.h Fri Dec 22 16:41:01 2017<br class="">@@ -53,6 +53,10 @@ public:<br class="">   // more information than the AddDecl class.<br class="">   void AddCXXRecordDecl(const CXXRecordDecl *Record);<br class=""><br class="">+  // Use this for ODR checking functions between modules.  This method compares<br class="">+  // more information than the AddDecl class.<br class="">+  void AddFunctionDecl(const FunctionDecl *Function);<br class="">+<br class="">   // Process SubDecls of the main Decl.  This method calls the DeclVisitor<br class="">   // while AddDecl does not.<br class="">   void AddSubDecl(const Decl *D);<br class=""><br class="">Modified: cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td?rev=321395&r1=321394&r2=321395&view=diff" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td?rev=321395&r1=321394&r2=321395&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td (original)<br class="">+++ cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td Fri Dec 22 16:41:01 2017<br class="">@@ -270,6 +270,29 @@ def note_module_odr_violation_mismatch_d<br class="">   "friend function %2|"<br class="">   "}1">;<br class=""><br class="">+def err_module_odr_violation_function : Error<<br class="">+  "%q0 has different definitions in different modules; "<br class="">+  "%select{definition in module '%2'|defined here}1 "<br class="">+  "first difference is "<br class="">+  "%select{"<br class="">+  "return type is %4|"<br class="">+  "%ordinal4 parameter with name %5|"<br class="">+  "%ordinal4 parameter with type %5%select{| decayed from %7}6|"<br class="">+  "%ordinal4 parameter with%select{out|}5 a default argument|"<br class="">+  "%ordinal4 parameter with a default argument|"<br class="">+  "function body"<br class="">+  "}3">;<br class="">+<br class="">+def note_module_odr_violation_function : Note<"but in '%0' found "<br class="">+  "%select{"<br class="">+  "different return type %2|"<br class="">+  "%ordinal2 parameter with name %3|"<br class="">+  "%ordinal2 parameter with type %3%select{| decayed from %5}4|"<br class="">+  "%ordinal2 parameter with%select{out|}3 a default argument|"<br class="">+  "%ordinal2 parameter with a different default argument|"<br class="">+  "a different body"<br class="">+  "}1">;<br class="">+<br class=""> def err_module_odr_violation_mismatch_decl_unknown : Error<<br class="">   "%q0 %select{with definition in module '%2'|defined here}1 has different "<br class="">   "definitions in different modules; first difference is this "<br class=""><br class="">Modified: cfe/trunk/include/clang/Serialization/ASTReader.h<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=321395&r1=321394&r2=321395&view=diff" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=321395&r1=321394&r2=321395&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)<br class="">+++ cfe/trunk/include/clang/Serialization/ASTReader.h Fri Dec 22 16:41:01 2017<br class="">@@ -1092,6 +1092,10 @@ private:<br class="">   llvm::SmallDenseMap<CXXRecordDecl *, llvm::SmallVector<DataPointers, 2>, 2><br class="">       PendingOdrMergeFailures;<br class=""><br class="">+  /// \brief Function definitions in which we found an ODR violation.<br class="">+  llvm::SmallDenseMap<FunctionDecl *, llvm::SmallVector<FunctionDecl *, 2>, 2><br class="">+      PendingFunctionOdrMergeFailures;<br class="">+<br class="">   /// \brief DeclContexts in which we have diagnosed an ODR violation.<br class="">   llvm::SmallPtrSet<DeclContext*, 2> DiagnosedOdrMergeFailures;<br class=""><br class=""><br class="">Modified: cfe/trunk/lib/AST/Decl.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=321395&r1=321394&r2=321395&view=diff" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=321395&r1=321394&r2=321395&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/AST/Decl.cpp (original)<br class="">+++ cfe/trunk/lib/AST/Decl.cpp Fri Dec 22 16:41:01 2017<br class="">@@ -26,6 +26,7 @@<br class=""> #include "clang/AST/Expr.h"<br class=""> #include "clang/AST/ExprCXX.h"<br class=""> #include "clang/AST/ExternalASTSource.h"<br class="">+#include "clang/AST/ODRHash.h"<br class=""> #include "clang/AST/PrettyPrinter.h"<br class=""> #include "clang/AST/Redeclarable.h"<br class=""> #include "clang/AST/Stmt.h"<br class="">@@ -3604,6 +3605,25 @@ unsigned FunctionDecl::getMemoryFunction<br class="">   return 0;<br class=""> }<br class=""><br class="">+unsigned FunctionDecl::getODRHash() {<br class="">+  if (HasODRHash)<br class="">+    return ODRHash;<br class="">+<br class="">+  if (FunctionDecl *Definition = getDefinition()) {<br class="">+    if (Definition != this) {<br class="">+      HasODRHash = true;<br class="">+      ODRHash = Definition->getODRHash();<br class="">+      return ODRHash;<br class="">+    }<br class="">+  }<br class="">+<br class="">+  class ODRHash Hash;<br class="">+  Hash.AddFunctionDecl(this);<br class="">+  HasODRHash = true;<br class="">+  ODRHash = Hash.CalculateHash();<br class="">+  return ODRHash;<br class="">+}<br class="">+<br class=""> //===----------------------------------------------------------------------===//<br class=""> // FieldDecl Implementation<br class=""> //===----------------------------------------------------------------------===//<br class=""><br class="">Modified: cfe/trunk/lib/AST/ODRHash.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ODRHash.cpp?rev=321395&r1=321394&r2=321395&view=diff" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ODRHash.cpp?rev=321395&r1=321394&r2=321395&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/AST/ODRHash.cpp (original)<br class="">+++ cfe/trunk/lib/AST/ODRHash.cpp Fri Dec 22 16:41:01 2017<br class="">@@ -466,6 +466,36 @@ void ODRHash::AddCXXRecordDecl(const CXX<br class="">   }<br class=""> }<br class=""><br class="">+void ODRHash::AddFunctionDecl(const FunctionDecl *Function) {<br class="">+  assert(Function && "Expecting non-null pointer.");<br class="">+<br class="">+  // Skip hashing these kinds of function.<br class="">+  if (Function->isImplicit()) return;<br class="">+  if (Function->isDefaulted()) return;<br class="">+  if (Function->isDeleted()) return;<br class="">+  if (!Function->hasBody()) return;<br class="">+  if (!Function->getBody()) return;<br class="">+<br class="">+  // Skip functions that are specializations or in specialization context.<br class="">+  const DeclContext *DC = Function;<br class="">+  while (DC) {<br class="">+    if (isa<ClassTemplateSpecializationDecl>(DC)) return;<br class="">+    if (auto *F = dyn_cast<FunctionDecl>(DC))<br class="">+      if (F->isFunctionTemplateSpecialization()) return;<br class="">+    DC = DC->getParent();<br class="">+  }<br class="">+<br class="">+  AddDecl(Function);<br class="">+<br class="">+  AddQualType(Function->getReturnType());<br class="">+<br class="">+  ID.AddInteger(Function->param_size());<br class="">+  for (auto Param : Function->parameters())<br class="">+    AddSubDecl(Param);<br class="">+<br class="">+  AddStmt(Function->getBody());<br class="">+}<br class="">+<br class=""> void ODRHash::AddDecl(const Decl *D) {<br class="">   assert(D && "Expecting non-null pointer.");<br class="">   D = D->getCanonicalDecl();<br class=""><br class="">Modified: cfe/trunk/lib/Serialization/ASTReader.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=321395&r1=321394&r2=321395&view=diff" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=321395&r1=321394&r2=321395&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)<br class="">+++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri Dec 22 16:41:01 2017<br class="">@@ -9235,8 +9235,16 @@ void ASTReader::finishPendingActions() {<br class="">       const FunctionDecl *Defn = nullptr;<br class="">       if (!getContext().getLangOpts().Modules || !FD->hasBody(Defn)) {<br class="">         FD->setLazyBody(PB->second);<br class="">-      } else<br class="">-        mergeDefinitionVisibility(const_cast<FunctionDecl*>(Defn), FD);<br class="">+      } else {<br class="">+        auto *NonConstDefn = const_cast<FunctionDecl*>(Defn);<br class="">+        mergeDefinitionVisibility(NonConstDefn, FD);<br class="">+<br class="">+        if (!FD->isLateTemplateParsed() &&<br class="">+            !NonConstDefn->isLateTemplateParsed() &&<br class="">+            FD->getODRHash() != NonConstDefn->getODRHash()) {<br class="">+          PendingFunctionOdrMergeFailures[FD].push_back(NonConstDefn);<br class="">+        }<br class="">+      }<br class="">       continue;<br class="">     }<br class=""><br class="">@@ -9253,7 +9261,8 @@ void ASTReader::finishPendingActions() {<br class=""> }<br class=""><br class=""> void ASTReader::diagnoseOdrViolations() {<br class="">-  if (PendingOdrMergeFailures.empty() && PendingOdrMergeChecks.empty())<br class="">+  if (PendingOdrMergeFailures.empty() && PendingOdrMergeChecks.empty() &&<br class="">+      PendingFunctionOdrMergeFailures.empty())<br class="">     return;<br class=""><br class="">   // Trigger the import of the full definition of each class that had any<br class="">@@ -9275,6 +9284,20 @@ void ASTReader::diagnoseOdrViolations()<br class="">     }<br class="">   }<br class=""><br class="">+  // Trigger the import of functions.<br class="">+  auto FunctionOdrMergeFailures = std::move(PendingFunctionOdrMergeFailures);<br class="">+  PendingFunctionOdrMergeFailures.clear();<br class="">+  for (auto &Merge : FunctionOdrMergeFailures) {<br class="">+    Merge.first->buildLookup();<br class="">+    Merge.first->decls_begin();<br class="">+    Merge.first->getBody();<br class="">+    for (auto &FD : Merge.second) {<br class="">+      FD->buildLookup();<br class="">+      FD->decls_begin();<br class="">+      FD->getBody();<br class="">+    }<br class="">+  }<br class="">+<br class="">   // For each declaration from a merged context, check that the canonical<br class="">   // definition of that context also contains a declaration of the same<br class="">   // entity.<br class="">@@ -9357,13 +9380,35 @@ void ASTReader::diagnoseOdrViolations()<br class="">     }<br class="">   }<br class=""><br class="">-  if (OdrMergeFailures.empty())<br class="">+  if (OdrMergeFailures.empty() && FunctionOdrMergeFailures.empty())<br class="">     return;<br class=""><br class="">   // Ensure we don't accidentally recursively enter deserialization while<br class="">   // we're producing our diagnostics.<br class="">   Deserializing RecursionGuard(this);<br class=""><br class="">+  // Common code for hashing helpers.<br class="">+  ODRHash Hash;<br class="">+  auto ComputeQualTypeODRHash = [&Hash](QualType Ty) {<br class="">+    Hash.clear();<br class="">+    Hash.AddQualType(Ty);<br class="">+    return Hash.CalculateHash();<br class="">+  };<br class="">+<br class="">+  auto ComputeODRHash = [&Hash](const Stmt *S) {<br class="">+    assert(S);<br class="">+    Hash.clear();<br class="">+    Hash.AddStmt(S);<br class="">+    return Hash.CalculateHash();<br class="">+  };<br class="">+<br class="">+  auto ComputeSubDeclODRHash = [&Hash](const Decl *D) {<br class="">+    assert(D);<br class="">+    Hash.clear();<br class="">+    Hash.AddSubDecl(D);<br class="">+    return Hash.CalculateHash();<br class="">+  };<br class="">+<br class="">   // Issue any pending ODR-failure diagnostics.<br class="">   for (auto &Merge : OdrMergeFailures) {<br class="">     // If we've already pointed out a specific problem with this class, don't<br class="">@@ -9411,13 +9456,6 @@ void ASTReader::diagnoseOdrViolations()<br class="">                  << SecondModule << Range << DiffType;<br class="">         };<br class=""><br class="">-        ODRHash Hash;<br class="">-        auto ComputeQualTypeODRHash = [&Hash](QualType Ty) {<br class="">-          Hash.clear();<br class="">-          Hash.AddQualType(Ty);<br class="">-          return Hash.CalculateHash();<br class="">-        };<br class="">-<br class="">         unsigned FirstNumBases = FirstDD->NumBases;<br class="">         unsigned FirstNumVBases = FirstDD->NumVBases;<br class="">         unsigned SecondNumBases = SecondDD->NumBases;<br class="">@@ -9520,14 +9558,12 @@ void ASTReader::diagnoseOdrViolations()<br class="">       if (FirstTemplate && SecondTemplate) {<br class="">         DeclHashes FirstTemplateHashes;<br class="">         DeclHashes SecondTemplateHashes;<br class="">-        ODRHash Hash;<br class=""><br class="">         auto PopulateTemplateParameterHashs =<br class="">-            [&Hash](DeclHashes &Hashes, const ClassTemplateDecl *TD) {<br class="">+            [&ComputeSubDeclODRHash](DeclHashes &Hashes,<br class="">+                                     const ClassTemplateDecl *TD) {<br class="">               for (auto *D : TD->getTemplateParameters()->asArray()) {<br class="">-                Hash.clear();<br class="">-                Hash.AddSubDecl(D);<br class="">-                Hashes.emplace_back(D, Hash.CalculateHash());<br class="">+                Hashes.emplace_back(D, ComputeSubDeclODRHash(D));<br class="">               }<br class="">             };<br class=""><br class="">@@ -9696,18 +9732,15 @@ void ASTReader::diagnoseOdrViolations()<br class=""><br class="">       DeclHashes FirstHashes;<br class="">       DeclHashes SecondHashes;<br class="">-      ODRHash Hash;<br class=""><br class="">-      auto PopulateHashes = [&Hash, FirstRecord](DeclHashes &Hashes,<br class="">-                                                 CXXRecordDecl *Record) {<br class="">+      auto PopulateHashes = [&ComputeSubDeclODRHash, FirstRecord](<br class="">+                                DeclHashes &Hashes, CXXRecordDecl *Record) {<br class="">         for (auto *D : Record->decls()) {<br class="">           // Due to decl merging, the first CXXRecordDecl is the parent of<br class="">           // Decls in both records.<br class="">           if (!ODRHash::isWhitelistedDecl(D, FirstRecord))<br class="">             continue;<br class="">-          Hash.clear();<br class="">-          Hash.AddSubDecl(D);<br class="">-          Hashes.emplace_back(D, Hash.CalculateHash());<br class="">+          Hashes.emplace_back(D, ComputeSubDeclODRHash(D));<br class="">         }<br class="">       };<br class="">       PopulateHashes(FirstHashes, FirstRecord);<br class="">@@ -9901,19 +9934,6 @@ void ASTReader::diagnoseOdrViolations()<br class="">                << SecondModule << Range << DiffType;<br class="">       };<br class=""><br class="">-      auto ComputeODRHash = [&Hash](const Stmt* S) {<br class="">-        assert(S);<br class="">-        Hash.clear();<br class="">-        Hash.AddStmt(S);<br class="">-        return Hash.CalculateHash();<br class="">-      };<br class="">-<br class="">-      auto ComputeQualTypeODRHash = [&Hash](QualType Ty) {<br class="">-        Hash.clear();<br class="">-        Hash.AddQualType(Ty);<br class="">-        return Hash.CalculateHash();<br class="">-      };<br class="">-<br class="">       switch (FirstDiffType) {<br class="">       case Other:<br class="">       case EndOfClass:<br class="">@@ -10488,6 +10508,160 @@ void ASTReader::diagnoseOdrViolations()<br class="">         << Merge.first;<br class="">     }<br class="">   }<br class="">+<br class="">+  // Issue ODR failures diagnostics for functions.<br class="">+  for (auto &Merge : FunctionOdrMergeFailures) {<br class="">+    enum ODRFunctionDifference {<br class="">+      ReturnType,<br class="">+      ParameterName,<br class="">+      ParameterType,<br class="">+      ParameterSingleDefaultArgument,<br class="">+      ParameterDifferentDefaultArgument,<br class="">+      FunctionBody,<br class="">+    };<br class="">+<br class="">+    FunctionDecl *FirstFunction = Merge.first;<br class="">+    std::string FirstModule = getOwningModuleNameForDiagnostic(FirstFunction);<br class="">+<br class="">+    bool Diagnosed = false;<br class="">+    for (auto &SecondFunction : Merge.second) {<br class="">+<br class="">+      if (FirstFunction == SecondFunction)<br class="">+        continue;<br class="">+<br class="">+      std::string SecondModule =<br class="">+          getOwningModuleNameForDiagnostic(SecondFunction);<br class="">+<br class="">+      auto ODRDiagError = [FirstFunction, &FirstModule,<br class="">+                           this](SourceLocation Loc, SourceRange Range,<br class="">+                                 ODRFunctionDifference DiffType) {<br class="">+        return Diag(Loc, diag::err_module_odr_violation_function)<br class="">+               << FirstFunction << FirstModule.empty() << FirstModule << Range<br class="">+               << DiffType;<br class="">+      };<br class="">+      auto ODRDiagNote = [&SecondModule, this](SourceLocation Loc,<br class="">+                                               SourceRange Range,<br class="">+                                               ODRFunctionDifference DiffType) {<br class="">+        return Diag(Loc, diag::note_module_odr_violation_function)<br class="">+               << SecondModule << Range << DiffType;<br class="">+      };<br class="">+<br class="">+      if (ComputeQualTypeODRHash(FirstFunction->getReturnType()) !=<br class="">+          ComputeQualTypeODRHash(SecondFunction->getReturnType())) {<br class="">+        ODRDiagError(FirstFunction->getReturnTypeSourceRange().getBegin(),<br class="">+                     FirstFunction->getReturnTypeSourceRange(), ReturnType)<br class="">+            << FirstFunction->getReturnType();<br class="">+        ODRDiagNote(SecondFunction->getReturnTypeSourceRange().getBegin(),<br class="">+                    SecondFunction->getReturnTypeSourceRange(), ReturnType)<br class="">+            << SecondFunction->getReturnType();<br class="">+        Diagnosed = true;<br class="">+        break;<br class="">+      }<br class="">+<br class="">+      assert(FirstFunction->param_size() == SecondFunction->param_size() &&<br class="">+             "Merged functions with different number of parameters");<br class="">+<br class="">+      auto ParamSize = FirstFunction->param_size();<br class="">+      bool ParameterMismatch = false;<br class="">+      for (unsigned I = 0; I < ParamSize; ++I) {<br class="">+        auto *FirstParam = FirstFunction->getParamDecl(I);<br class="">+        auto *SecondParam = SecondFunction->getParamDecl(I);<br class="">+<br class="">+        assert(getContext().hasSameType(FirstParam->getType(),<br class="">+                                      SecondParam->getType()) &&<br class="">+               "Merged function has different parameter types.");<br class="">+<br class="">+        if (FirstParam->getDeclName() != SecondParam->getDeclName()) {<br class="">+          ODRDiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),<br class="">+                       ParameterName)<br class="">+              << I + 1 << FirstParam->getDeclName();<br class="">+          ODRDiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),<br class="">+                      ParameterName)<br class="">+              << I + 1 << SecondParam->getDeclName();<br class="">+          ParameterMismatch = true;<br class="">+          break;<br class="">+        };<br class="">+<br class="">+        QualType FirstParamType = FirstParam->getType();<br class="">+        QualType SecondParamType = SecondParam->getType();<br class="">+        if (FirstParamType != SecondParamType &&<br class="">+            ComputeQualTypeODRHash(FirstParamType) !=<br class="">+                ComputeQualTypeODRHash(SecondParamType)) {<br class="">+          if (const DecayedType *ParamDecayedType =<br class="">+                  FirstParamType->getAs<DecayedType>()) {<br class="">+            ODRDiagError(FirstParam->getLocation(),<br class="">+                         FirstParam->getSourceRange(), ParameterType)<br class="">+                << (I + 1) << FirstParamType << true<br class="">+                << ParamDecayedType->getOriginalType();<br class="">+          } else {<br class="">+            ODRDiagError(FirstParam->getLocation(),<br class="">+                         FirstParam->getSourceRange(), ParameterType)<br class="">+                << (I + 1) << FirstParamType << false;<br class="">+          }<br class="">+<br class="">+          if (const DecayedType *ParamDecayedType =<br class="">+                  SecondParamType->getAs<DecayedType>()) {<br class="">+            ODRDiagNote(SecondParam->getLocation(),<br class="">+                        SecondParam->getSourceRange(), ParameterType)<br class="">+                << (I + 1) << SecondParamType << true<br class="">+                << ParamDecayedType->getOriginalType();<br class="">+          } else {<br class="">+            ODRDiagNote(SecondParam->getLocation(),<br class="">+                        SecondParam->getSourceRange(), ParameterType)<br class="">+                << (I + 1) << SecondParamType << false;<br class="">+          }<br class="">+          ParameterMismatch = true;<br class="">+          break;<br class="">+        }<br class="">+<br class="">+        const Expr *FirstInit = FirstParam->getInit();<br class="">+        const Expr *SecondInit = SecondParam->getInit();<br class="">+        if ((FirstInit == nullptr) != (SecondInit == nullptr)) {<br class="">+          ODRDiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),<br class="">+                       ParameterSingleDefaultArgument)<br class="">+              << (I + 1) << (FirstInit == nullptr)<br class="">+              << (FirstInit ? FirstInit->getSourceRange() : SourceRange());<br class="">+          ODRDiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),<br class="">+                      ParameterSingleDefaultArgument)<br class="">+              << (I + 1) << (SecondInit == nullptr)<br class="">+              << (SecondInit ? SecondInit->getSourceRange() : SourceRange());<br class="">+          ParameterMismatch = true;<br class="">+          break;<br class="">+        }<br class="">+<br class="">+        if (FirstInit && SecondInit &&<br class="">+            ComputeODRHash(FirstInit) != ComputeODRHash(SecondInit)) {<br class="">+          ODRDiagError(FirstParam->getLocation(), FirstParam->getSourceRange(),<br class="">+                       ParameterDifferentDefaultArgument)<br class="">+              << (I + 1) << FirstInit->getSourceRange();<br class="">+          ODRDiagNote(SecondParam->getLocation(), SecondParam->getSourceRange(),<br class="">+                      ParameterDifferentDefaultArgument)<br class="">+              << (I + 1) << SecondInit->getSourceRange();<br class="">+          ParameterMismatch = true;<br class="">+          break;<br class="">+        }<br class="">+<br class="">+        assert(ComputeSubDeclODRHash(FirstParam) ==<br class="">+                   ComputeSubDeclODRHash(SecondParam) &&<br class="">+               "Undiagnosed parameter difference.");<br class="">+      }<br class="">+<br class="">+      if (ParameterMismatch) {<br class="">+        Diagnosed = true;<br class="">+        break;<br class="">+      }<br class="">+<br class="">+      // If no error has been generated before now, assume the problem is in<br class="">+      // the body and generate a message.<br class="">+      ODRDiagError(FirstFunction->getLocation(),<br class="">+                   FirstFunction->getSourceRange(), FunctionBody);<br class="">+      ODRDiagNote(SecondFunction->getLocation(),<br class="">+                  SecondFunction->getSourceRange(), FunctionBody);<br class="">+      Diagnosed = true;<br class="">+      break;<br class="">+    }<br class="">+    assert(Diagnosed && "Unable to emit ODR diagnostic.");<br class="">+  }<br class=""> }<br class=""><br class=""> void ASTReader::StartedDeserializing() {<br class=""><br class="">Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=321395&r1=321394&r2=321395&view=diff" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=321395&r1=321394&r2=321395&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)<br class="">+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Fri Dec 22 16:41:01 2017<br class="">@@ -796,6 +796,9 @@ void ASTDeclReader::VisitFunctionDecl(Fu<br class="">   FD->setCachedLinkage(Linkage(Record.readInt()));<br class="">   FD->EndRangeLoc = ReadSourceLocation();<br class=""><br class="">+  FD->ODRHash = Record.readInt();<br class="">+  FD->HasODRHash = true;<br class="">+<br class="">   switch ((FunctionDecl::TemplatedKind)Record.readInt()) {<br class="">   case FunctionDecl::TK_NonTemplate:<br class="">     mergeRedeclarable(FD, Redecl);<br class=""><br class="">Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=321395&r1=321394&r2=321395&view=diff" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=321395&r1=321394&r2=321395&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)<br class="">+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Fri Dec 22 16:41:01 2017<br class="">@@ -538,6 +538,8 @@ void ASTDeclWriter::VisitFunctionDecl(Fu<br class="">   Record.push_back(D->getLinkageInternal());<br class="">   Record.AddSourceLocation(D->getLocEnd());<br class=""><br class="">+  Record.push_back(D->getODRHash());<br class="">+<br class="">   Record.push_back(D->getTemplatedKind());<br class="">   switch (D->getTemplatedKind()) {<br class="">   case FunctionDecl::TK_NonTemplate:<br class="">@@ -2072,6 +2074,7 @@ void ASTWriter::WriteDeclAbbrevs() {<br class="">   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // LateParsed<br class="">   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // Linkage<br class="">   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // LocEnd<br class="">+  Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // ODRHash<br class="">   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // TemplateKind<br class="">   // This Array slurps the rest of the record. Fortunately we want to encode<br class="">   // (nearly) all the remaining (variable number of) fields in the same way.<br class=""><br class="">Modified: cfe/trunk/test/Modules/odr_hash.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash.cpp?rev=321395&r1=321394&r2=321395&view=diff" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash.cpp?rev=321395&r1=321394&r2=321395&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/test/Modules/odr_hash.cpp (original)<br class="">+++ cfe/trunk/test/Modules/odr_hash.cpp Fri Dec 22 16:41:01 2017<br class="">@@ -557,11 +557,11 @@ S10 s10;<br class=""><br class=""> #if defined(FIRST)<br class=""> struct S11 {<br class="">-  void A(int x) {}<br class="">+  void A(int x);<br class=""> };<br class=""> #elif defined(SECOND)<br class=""> struct S11 {<br class="">-  void A(int y) {}<br class="">+  void A(int y);<br class=""> };<br class=""> #else<br class=""> S11 s11;<br class="">@@ -571,11 +571,11 @@ S11 s11;<br class=""><br class=""> #if defined(FIRST)<br class=""> struct S12 {<br class="">-  void A(int x) {}<br class="">+  void A(int x);<br class=""> };<br class=""> #elif defined(SECOND)<br class=""> struct S12 {<br class="">-  void A(int x = 1) {}<br class="">+  void A(int x = 1);<br class=""> };<br class=""> #else<br class=""> S12 s12;<br class="">@@ -585,11 +585,11 @@ S12 s12;<br class=""><br class=""> #if defined(FIRST)<br class=""> struct S13 {<br class="">-  void A(int x = 1 + 0) {}<br class="">+  void A(int x = 1 + 0);<br class=""> };<br class=""> #elif defined(SECOND)<br class=""> struct S13 {<br class="">-  void A(int x = 1) {}<br class="">+  void A(int x = 1);<br class=""> };<br class=""> #else<br class=""> S13 s13;<br class="">@@ -599,11 +599,11 @@ S13 s13;<br class=""><br class=""> #if defined(FIRST)<br class=""> struct S14 {<br class="">-  void A(int x[2]) {}<br class="">+  void A(int x[2]);<br class=""> };<br class=""> #elif defined(SECOND)<br class=""> struct S14 {<br class="">-  void A(int x[3]) {}<br class="">+  void A(int x[3]);<br class=""> };<br class=""> #else<br class=""> S14 s14;<br class="">@@ -2751,14 +2751,14 @@ namespace DefaultArguments {<br class=""> template <typename T><br class=""> struct S {<br class="">   struct R {<br class="">-    void foo(T x = 0) {}<br class="">+    void foo(T x = 0);<br class="">   };<br class=""> };<br class=""> #elif defined(SECOND)<br class=""> template <typename T><br class=""> struct S {<br class="">   struct R {<br class="">-    void foo(T x = 1) {}<br class="">+    void foo(T x = 1);<br class="">   };<br class=""> };<br class=""> #else<br class="">@@ -2771,13 +2771,13 @@ void run() {<br class=""><br class=""> #if defined(FIRST)<br class=""> template <typename alpha> struct Bravo {<br class="">-  void charlie(bool delta = false) {}<br class="">+  void charlie(bool delta = false);<br class=""> };<br class=""> typedef Bravo<char> echo;<br class=""> echo foxtrot;<br class=""> #elif defined(SECOND)<br class=""> template <typename alpha> struct Bravo {<br class="">-  void charlie(bool delta = (false)) {}<br class="">+  void charlie(bool delta = (false));<br class=""> };<br class=""> typedef Bravo<char> echo;<br class=""> echo foxtrot;<br class="">@@ -2788,6 +2788,142 @@ Bravo<char> golf;<br class=""> #endif<br class=""> }  // namespace DefaultArguments<br class=""><br class="">+namespace FunctionDecl {<br class="">+#if defined(FIRST)<br class="">+struct S1 {};<br class="">+S1 s1a;<br class="">+#elif defined(SECOND)<br class="">+struct S1 {};<br class="">+#else<br class="">+S1 s1;<br class="">+#endif<br class="">+<br class="">+#if defined(FIRST)<br class="">+struct S2 {<br class="">+  S2() = default;<br class="">+};<br class="">+S2 s2a = S2();<br class="">+#elif defined(SECOND)<br class="">+struct S2 {<br class="">+  S2() = default;<br class="">+};<br class="">+#else<br class="">+S2 s2;<br class="">+#endif<br class="">+<br class="">+#if defined(FIRST)<br class="">+struct S3 {<br class="">+  S3() = delete;<br class="">+};<br class="">+S3* s3c;<br class="">+#elif defined(SECOND)<br class="">+struct S3 {<br class="">+  S3() = delete;<br class="">+};<br class="">+#else<br class="">+S3* s3;<br class="">+#endif<br class="">+<br class="">+#if defined(FIRST) || defined(SECOND)<br class="">+int F1(int x, float y = 2.7) { return 1; }<br class="">+#else<br class="">+int I1 = F1(1);<br class="">+#endif<br class="">+<br class="">+#if defined(FIRST)<br class="">+int F2() { return 1; }<br class="">+#elif defined(SECOND)<br class="">+double F2() { return 1; }<br class="">+#else<br class="">+int I2 = F2();<br class="">+// expected-error@-1 {{call to 'F2' is ambiguous}}<br class="">+// <a href="mailto:expected-note@first.h" class="">expected-note@first.h</a>:* {{candidate function}}<br class="">+// <a href="mailto:expected-note@second.h" class="">expected-note@second.h</a>:* {{candidate function}}<br class="">+#endif<br class="">+<br class="">+#if defined(FIRST)<br class="">+int F3(float) { return 1; }<br class="">+#elif defined(SECOND)<br class="">+int F3(double) { return 1; }<br class="">+#else<br class="">+int I3 = F3(1);<br class="">+// expected-error@-1 {{call to 'F3' is ambiguous}}<br class="">+// <a href="mailto:expected-note@first.h" class="">expected-note@first.h</a>:* {{candidate function}}<br class="">+// <a href="mailto:expected-note@second.h" class="">expected-note@second.h</a>:* {{candidate function}}<br class="">+#endif<br class="">+<br class="">+#if defined(FIRST)<br class="">+int F4(int x) { return 1; }<br class="">+#elif defined(SECOND)<br class="">+int F4(int y) { return 1; }<br class="">+#else<br class="">+int I4 = F4(1);<br class="">+// <a href="mailto:expected-error@second.h" class="">expected-error@second.h</a>:* {{'FunctionDecl::F4' has different definitions in different modules; definition in module 'SecondModule' first difference is 1st parameter with name 'y'}}<br class="">+// <a href="mailto:expected-note@first.h" class="">expected-note@first.h</a>:* {{but in 'FirstModule' found 1st parameter with name 'x'}}<br class="">+#endif<br class="">+<br class="">+#if defined(FIRST)<br class="">+int F5(int x) { return 1; }<br class="">+#elif defined(SECOND)<br class="">+int F5(int x = 1) { return 1; }<br class="">+#else<br class="">+int I5 = F6(1);<br class="">+// <a href="mailto:expected-error@second.h" class="">expected-error@second.h</a>:* {{'FunctionDecl::F5' has different definitions in different modules; definition in module 'SecondModule' first difference is 1st parameter without a default argument}}<br class="">+// <a href="mailto:expected-note@first.h" class="">expected-note@first.h</a>:* {{but in 'FirstModule' found 1st parameter with a default argument}}<br class="">+#endif<br class="">+<br class="">+#if defined(FIRST)<br class="">+int F6(int x = 2) { return 1; }<br class="">+#elif defined(SECOND)<br class="">+int F6(int x = 1) { return 1; }<br class="">+#else<br class="">+int I6 = F6(1);<br class="">+// <a href="mailto:expected-error@second.h" class="">expected-error@second.h</a>:* {{'FunctionDecl::F6' has different definitions in different modules; definition in module 'SecondModule' first difference is 1st parameter with a default argument}}<br class="">+// <a href="mailto:expected-note@first.h" class="">expected-note@first.h</a>:* {{but in 'FirstModule' found 1st parameter with a different default argument}}<br class="">+#endif<br class="">+<br class="">+using I = int;<br class="">+#if defined(FIRST)<br class="">+I F7() { return 0; }<br class="">+#elif defined(SECOND)<br class="">+int F7() { return 0; }<br class="">+#else<br class="">+int I7 = F7();<br class="">+// <a href="mailto:expected-error@second.h" class="">expected-error@second.h</a>:* {{'FunctionDecl::F7' has different definitions in different modules; definition in module 'SecondModule' first difference is return type is 'int'}}<br class="">+// <a href="mailto:expected-note@first.h" class="">expected-note@first.h</a>:* {{but in 'FirstModule' found different return type 'FunctionDecl::I' (aka 'int')}}<br class="">+#endif<br class="">+<br class="">+#if defined(FIRST)<br class="">+int F8(int) { return 0; }<br class="">+#elif defined(SECOND)<br class="">+int F8(I) { return 0; }<br class="">+#else<br class="">+int I8 = F8(1);<br class="">+// <a href="mailto:expected-error@second.h" class="">expected-error@second.h</a>:* {{'FunctionDecl::F8' has different definitions in different modules; definition in module 'SecondModule' first difference is 1st parameter with type 'FunctionDecl::I' (aka 'int')}}<br class="">+// <a href="mailto:expected-note@first.h" class="">expected-note@first.h</a>:* {{but in 'FirstModule' found 1st parameter with type 'int'}}<br class="">+#endif<br class="">+<br class="">+#if defined(FIRST)<br class="">+int F9(int[1]) { return 0; }<br class="">+#elif defined(SECOND)<br class="">+int F9(int[2]) { return 0; }<br class="">+#else<br class="">+int I9 = F9(nullptr);<br class="">+// <a href="mailto:expected-error@second.h" class="">expected-error@second.h</a>:* {{'FunctionDecl::F9' has different definitions in different modules; definition in module 'SecondModule' first difference is 1st parameter with type 'int *' decayed from 'int [2]'}}<br class="">+// <a href="mailto:expected-note@first.h" class="">expected-note@first.h</a>:* {{but in 'FirstModule' found 1st parameter with type 'int *' decayed from 'int [1]'}}<br class="">+#endif<br class="">+<br class="">+#if defined(FIRST)<br class="">+int F10() { return 1; }<br class="">+#elif defined(SECOND)<br class="">+int F10() { return 2; }<br class="">+#else<br class="">+int I10 = F10();<br class="">+#endif<br class="">+// <a href="mailto:expected-error@second.h" class="">expected-error@second.h</a>:* {{'FunctionDecl::F10' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}<br class="">+// <a href="mailto:expected-note@first.h" class="">expected-note@first.h</a>:* {{but in 'FirstModule' found a different body}}<br class="">+}  // namespace FunctionDecl<br class="">+<br class=""> // Keep macros contained to one file.<br class=""> #ifdef FIRST<br class=""> #undef FIRST<br class=""><br class=""><br class="">_______________________________________________<br class="">cfe-commits mailing list<br class=""><a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a><br class=""><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br class=""></div></div></blockquote></div><br class=""></div></div></div></blockquote></div><br class=""></body></html>