<div dir="ltr">I'm hitting the same issue as well.<div><br></div><div>Please let me know if there is anything I can do to get this fixed quickly.</div><div><br></div><div>/Eric</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jan 3, 2018 at 5:20 PM, Richard Trieu via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Vedant,<div><br></div><div>I'm looking into it.<div><div class="h5"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jan 3, 2018 at 11:12 AM, Vedant Kumar <span dir="ltr"><<a href="mailto:vsk@apple.com" target="_blank">vsk@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div>Oops, the build log was too big to attach. Resending with just the bot link, then:</div><div><a href="http://lab.llvm.org:8080/green/view/Experimental/job/clang-stage2-coverage-R/2193/consoleText" target="_blank">http://lab.llvm.org:8080/green<wbr>/view/Experimental/job/clang-<wbr>stage2-coverage-R/2193/console<wbr>Text</a></div><div><br></div><div>vedant</div><br><div><blockquote type="cite"><div><div class="m_-2505169260272605186h5"><div>On Jan 3, 2018, at 11:09 AM, Vedant Kumar <<a href="mailto:vsk@apple.com" target="_blank">vsk@apple.com</a>> wrote:</div><br class="m_-2505169260272605186m_-3575192144528685162Apple-interchange-newline"></div></div><div><div><div class="m_-2505169260272605186h5"><div style="word-wrap:break-word">Hi Richard,<div><br></div><div>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><br></div><div><pre style="word-wrap:break-word;white-space:pre-wrap">[3685/3899] /Users/buildslave/jenkins/work<wbr>space/clang-stage2-coverage-R/<wbr>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/wo<wbr>rkspace/clang-stage2-coverage-<wbr>R/llvm/tools/lld/COFF -I/Users/buildslave/jenkins/wo<wbr>rkspace/clang-stage2-coverage-<wbr>R/llvm/tools/lld/include -Itools/lld/include -I/usr/include/libxml2 -Iinclude -I/Users/buildslave/jenkins/wo<wbr>rkspace/clang-stage2-coverage-<wbr>R/llvm/include -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability<wbr>-new -std=c++11 -fmodules -fmodules-cache-path=/Users/bu<wbr>ildslave/jenkins/workspace/cla<wbr>ng-stage2-coverage-R/clang-bui<wbr>ld/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='/Use<wbr>rs/buildslave/jenkins/workspac<wbr>e/clang-stage2-coverage-R/<wbr>clang-build/profiles/%6m.<wbr>profraw' -fcoverage-mapping -O3 -DNDEBUG    -fno-exceptions -fno-rtti -MMD -MT tools/lld/COFF/CMakeFiles/lldC<wbr>OFF.dir/PDB.cpp.o -MF tools/lld/COFF/CMakeFiles/lldC<wbr>OFF.dir/PDB.cpp.o.d -o tools/lld/COFF/CMakeFiles/lldC<wbr>OFF.dir/PDB.cpp.o -c /Users/buildslave/jenkins/work<wbr>space/clang-stage2-coverage-R/<wbr>llvm/tools/lld/COFF/PDB.cpp
FAILED: tools/lld/COFF/CMakeFiles/lldC<wbr>OFF.dir/PDB.cpp.o 
/Users/buildslave/jenkins/work<wbr>space/clang-stage2-coverage-R/<wbr>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/wo<wbr>rkspace/clang-stage2-coverage-<wbr>R/llvm/tools/lld/COFF -I/Users/buildslave/jenkins/wo<wbr>rkspace/clang-stage2-coverage-<wbr>R/llvm/tools/lld/include -Itools/lld/include -I/usr/include/libxml2 -Iinclude -I/Users/buildslave/jenkins/wo<wbr>rkspace/clang-stage2-coverage-<wbr>R/llvm/include -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability<wbr>-new -std=c++11 -fmodules -fmodules-cache-path=/Users/bu<wbr>ildslave/jenkins/workspace/cla<wbr>ng-stage2-coverage-R/clang-bui<wbr>ld/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='/Use<wbr>rs/buildslave/jenkins/workspac<wbr>e/clang-stage2-coverage-R/<wbr>clang-build/profiles/%6m.<wbr>profraw' -fcoverage-mapping -O3 -DNDEBUG    -fno-exceptions -fno-rtti -MMD -MT tools/lld/COFF/CMakeFiles/lldC<wbr>OFF.dir/PDB.cpp.o -MF tools/lld/COFF/CMakeFiles/lldC<wbr>OFF.dir/PDB.cpp.o.d -o tools/lld/COFF/CMakeFiles/lldC<wbr>OFF.dir/PDB.cpp.o -c /Users/buildslave/jenkins/work<wbr>space/clang-stage2-coverage-R/<wbr>llvm/tools/lld/COFF/PDB.cpp
In module 'std' imported from /Users/buildslave/jenkins/work<wbr>space/clang-stage2-coverage-R/<wbr>llvm/tools/lld/COFF/Config.h:<wbr>16:
/Users/buildslave/jenkins/work<wbr>space/clang-stage2-coverage-R/<wbr>host-compiler/include/c++/v1/<wbr>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)
    ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~<wbr>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<wbr>~~~~~~~~~~~
/Users/buildslave/jenkins/work<wbr>space/clang-stage2-coverage-R/<wbr>host-compiler/include/c++/v1/<wbr>list:389:10: note: but in 'std.list' found a different body
    bool operator==(const __list_iterator& __x, const __list_iterator& __y)
    ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~<wbr>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<wbr>~~~~~~~~~~~
/Users/buildslave/jenkins/work<wbr>space/clang-stage2-coverage-R/<wbr>host-compiler/include/c++/v1/<wbr>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)
     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~<wbr>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<wbr>~~~~~~~~~~~
/Users/buildslave/jenkins/work<wbr>space/clang-stage2-coverage-R/<wbr>host-compiler/include/c++/v1/<wbr>list:394:11: note: but in 'std.list' found a different body
     bool operator!=(const __list_iterator& __x, const __list_iterator& __y)
     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~<wbr>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<wbr>~~~~~~~~~~~
2 errors generated.</pre><div>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><br></div><div>I've temporarily disabled building with modules enabled on the bot. Could you take a look?</div><div><br></div><div>thanks,</div><div>vedant</div><div><br></div><div><a href="http://lab.llvm.org:8080/green/view/Experimental/job/clang-stage2-coverage-R/2193" target="_blank">http://lab.llvm.org:8080/green<wbr>/view/Experimental/job/clang-<wbr>stage2-coverage-R/2193</a></div><div><br></div><div></div></div></div></div><span id="m_-2505169260272605186m_-3575192144528685162cid:A9C968BE-334D-4AE4-B4E0-2D3EEE7AB3BD@apple.com"><coverage-build-log.txt></span><div><div class="m_-2505169260272605186h5"><div style="word-wrap:break-word"><div></div><div><br></div><div><br></div><div><br><div><blockquote type="cite"><div>On Dec 22, 2017, at 4:41 PM, Richard Trieu via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>> wrote:</div><br class="m_-2505169260272605186m_-3575192144528685162Apple-interchange-newline"><div><div>Author: rtrieu<br>Date: Fri Dec 22 16:41:01 2017<br>New Revision: 321395<br><br>URL: <a href="http://llvm.org/viewvc/llvm-project?rev=321395&view=rev" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject?rev=321395&view=rev</a><br>Log:<br>[ODRHash] Support ODR violation detection in functions.<br><br>Extend the hashing to functions, which allows detection of function definition<br>mismatches across modules.  This is a re-commit of r320230.<br><br>Modified:<br>    cfe/trunk/include/clang/AST<wbr>/Decl.h<br>    cfe/trunk/include/clang/AST<wbr>/ODRHash.h<br>    cfe/trunk/include/clang/Bas<wbr>ic/DiagnosticSerializationKind<wbr><a href="http://s.td">s.td</a><br>    cfe/trunk/include/clang/Ser<wbr>ialization/ASTReader.h<br>    cfe/trunk/lib/AST/Decl.cpp<br>    cfe/trunk/lib/AST/ODRHash.c<wbr>pp<br>    cfe/trunk/lib/Serialization<wbr>/ASTReader.cpp<br>    cfe/trunk/lib/Serialization<wbr>/ASTReaderDecl.cpp<br>    cfe/trunk/lib/Serialization<wbr>/ASTWriterDecl.cpp<br>    cfe/trunk/test/Modules/odr_<wbr>hash.cpp<br><br>Modified: cfe/trunk/include/clang/AST/De<wbr>cl.h<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=321395&r1=321394&r2=321395&view=diff" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/include/clang/<wbr>AST/Decl.h?rev=321395&r1=<wbr>321394&r2=321395&view=diff</a><br>==============================<wbr>==============================<wbr>==================<br>--- cfe/trunk/include/clang/AST/De<wbr>cl.h (original)<br>+++ cfe/trunk/include/clang/AST/De<wbr>cl.h Fri Dec 22 16:41:01 2017<br>@@ -1759,6 +1759,11 @@ protected:<br>   unsigned IsCopyDeductionCandidate : 1;<br><br> private:<br>+<br>+  /// Store the ODRHash after first calculation.<br>+  unsigned HasODRHash : 1;<br>+  unsigned ODRHash;<br>+<br>   /// \brief End part of this FunctionDecl's source range.<br>   ///<br>   /// We could compute the full range in getSourceRange(). However, when we're<br>@@ -1841,8 +1846,9 @@ protected:<br>         IsExplicitlyDefaulted(<wbr>false), HasImplicitReturnZero(false),<br>         IsLateTemplateParsed(f<wbr>alse), IsConstexpr(isConstexprSpecifi<wbr>ed),<br>         InstantiationIsPending<wbr>(false), UsesSEHTry(false), HasSkippedBody(false),<br>-        WillHaveBody(false), IsCopyDeductionCandidate(false<wbr>),<br>-        EndRangeLoc(NameInfo.ge<wbr>tEndLoc()), DNLoc(NameInfo.getInfo()) {}<br>+        WillHaveBody(false), IsCopyDeductionCandidate(false<wbr>), HasODRHash(false),<br>+        ODRHash(0), EndRangeLoc(NameInfo.getEndLoc<wbr>()),<br>+        DNLoc(NameInfo.getInfo(<wbr>)) {}<br><br>   using redeclarable_base = Redeclarable<FunctionDecl>;<br><br>@@ -2439,6 +2445,10 @@ public:<br>   /// returns 0.<br>   unsigned getMemoryFunctionKind() const;<br><br>+  /// \brief Returns ODRHash of the function.  This value is calculated and<br>+  /// stored on first call, then the stored value returned on the other calls.<br>+  unsigned getODRHash();<br>+<br>   // Implement isa/cast/dyncast/etc.<br>   static bool classof(const Decl *D) { return classofKind(D->getKind()); }<br>   static bool classofKind(Kind K) {<br><br>Modified: cfe/trunk/include/clang/AST/OD<wbr>RHash.h<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ODRHash.h?rev=321395&r1=321394&r2=321395&view=diff" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/include/clang/<wbr>AST/ODRHash.h?rev=321395&r1=<wbr>321394&r2=321395&view=diff</a><br>==============================<wbr>==============================<wbr>==================<br>--- cfe/trunk/include/clang/AST/OD<wbr>RHash.h (original)<br>+++ cfe/trunk/include/clang/AST/OD<wbr>RHash.h Fri Dec 22 16:41:01 2017<br>@@ -53,6 +53,10 @@ public:<br>   // more information than the AddDecl class.<br>   void AddCXXRecordDecl(const CXXRecordDecl *Record);<br><br>+  // Use this for ODR checking functions between modules.  This method compares<br>+  // more information than the AddDecl class.<br>+  void AddFunctionDecl(const FunctionDecl *Function);<br>+<br>   // Process SubDecls of the main Decl.  This method calls the DeclVisitor<br>   // while AddDecl does not.<br>   void AddSubDecl(const Decl *D);<br><br>Modified: cfe/trunk/include/clang/Basic/<wbr>DiagnosticSerializationKinds.t<wbr>d<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td?rev=321395&r1=321394&r2=321395&view=diff" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/include/clang/<wbr>Basic/DiagnosticSerializationK<wbr>inds.td?rev=321395&r1=321394&<wbr>r2=321395&view=diff</a><br>==============================<wbr>==============================<wbr>==================<br>--- cfe/trunk/include/clang/Basic/<wbr>DiagnosticSerializationKinds.t<wbr>d (original)<br>+++ cfe/trunk/include/clang/Basic/<wbr>DiagnosticSerializationKinds.t<wbr>d Fri Dec 22 16:41:01 2017<br>@@ -270,6 +270,29 @@ def note_module_odr_violation_mism<wbr>atch_d<br>   "friend function %2|"<br>   "}1">;<br><br>+def err_module_odr_violation_funct<wbr>ion : Error<<br>+  "%q0 has different definitions in different modules; "<br>+  "%select{definition in module '%2'|defined here}1 "<br>+  "first difference is "<br>+  "%select{"<br>+  "return type is %4|"<br>+  "%ordinal4 parameter with name %5|"<br>+  "%ordinal4 parameter with type %5%select{| decayed from %7}6|"<br>+  "%ordinal4 parameter with%select{out|}5 a default argument|"<br>+  "%ordinal4 parameter with a default argument|"<br>+  "function body"<br>+  "}3">;<br>+<br>+def note_module_odr_violation_func<wbr>tion : Note<"but in '%0' found "<br>+  "%select{"<br>+  "different return type %2|"<br>+  "%ordinal2 parameter with name %3|"<br>+  "%ordinal2 parameter with type %3%select{| decayed from %5}4|"<br>+  "%ordinal2 parameter with%select{out|}3 a default argument|"<br>+  "%ordinal2 parameter with a different default argument|"<br>+  "a different body"<br>+  "}1">;<br>+<br> def err_module_odr_violation_misma<wbr>tch_decl_unknown : Error<<br>   "%q0 %select{with definition in module '%2'|defined here}1 has different "<br>   "definitions in different modules; first difference is this "<br><br>Modified: cfe/trunk/include/clang/Serial<wbr>ization/ASTReader.h<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=321395&r1=321394&r2=321395&view=diff" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/include/clang/<wbr>Serialization/ASTReader.h?rev=<wbr>321395&r1=321394&r2=321395&<wbr>view=diff</a><br>==============================<wbr>==============================<wbr>==================<br>--- cfe/trunk/include/clang/Serial<wbr>ization/ASTReader.h (original)<br>+++ cfe/trunk/include/clang/Serial<wbr>ization/ASTReader.h Fri Dec 22 16:41:01 2017<br>@@ -1092,6 +1092,10 @@ private:<br>   llvm::SmallDenseMap<CXXRecor<wbr>dDecl *, llvm::SmallVector<DataPointers<wbr>, 2>, 2><br>       PendingOdrMergeFailures;<br><br>+  /// \brief Function definitions in which we found an ODR violation.<br>+  llvm::SmallDenseMap<FunctionD<wbr>ecl *, llvm::SmallVector<FunctionDecl *, 2>, 2><br>+      PendingFunctionOdrMergeFa<wbr>ilures;<br>+<br>   /// \brief DeclContexts in which we have diagnosed an ODR violation.<br>   llvm::SmallPtrSet<DeclContex<wbr>t*, 2> DiagnosedOdrMergeFailures;<br><br><br>Modified: cfe/trunk/lib/AST/Decl.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=321395&r1=321394&r2=321395&view=diff" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/AST/Decl.<wbr>cpp?rev=321395&r1=321394&r2=<wbr>321395&view=diff</a><br>==============================<wbr>==============================<wbr>==================<br>--- cfe/trunk/lib/AST/Decl.cpp (original)<br>+++ cfe/trunk/lib/AST/Decl.cpp Fri Dec 22 16:41:01 2017<br>@@ -26,6 +26,7 @@<br> #include "clang/AST/Expr.h"<br> #include "clang/AST/ExprCXX.h"<br> #include "clang/AST/ExternalASTSource.h<wbr>"<br>+#include "clang/AST/ODRHash.h"<br> #include "clang/AST/PrettyPrinter.h"<br> #include "clang/AST/Redeclarable.h"<br> #include "clang/AST/Stmt.h"<br>@@ -3604,6 +3605,25 @@ unsigned FunctionDecl::getMemoryFunctio<wbr>n<br>   return 0;<br> }<br><br>+unsigned FunctionDecl::getODRHash() {<br>+  if (HasODRHash)<br>+    return ODRHash;<br>+<br>+  if (FunctionDecl *Definition = getDefinition()) {<br>+    if (Definition != this) {<br>+      HasODRHash = true;<br>+      ODRHash = Definition->getODRHash();<br>+      return ODRHash;<br>+    }<br>+  }<br>+<br>+  class ODRHash Hash;<br>+  Hash.AddFunctionDecl(this);<br>+  HasODRHash = true;<br>+  ODRHash = Hash.CalculateHash();<br>+  return ODRHash;<br>+}<br>+<br> //===-------------------------<wbr>------------------------------<wbr>---------------===//<br> // FieldDecl Implementation<br> //===-------------------------<wbr>------------------------------<wbr>---------------===//<br><br>Modified: cfe/trunk/lib/AST/ODRHash.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ODRHash.cpp?rev=321395&r1=321394&r2=321395&view=diff" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/AST/ODRHas<wbr>h.cpp?rev=321395&r1=321394&r2=<wbr>321395&view=diff</a><br>==============================<wbr>==============================<wbr>==================<br>--- cfe/trunk/lib/AST/ODRHash.cpp (original)<br>+++ cfe/trunk/lib/AST/ODRHash.cpp Fri Dec 22 16:41:01 2017<br>@@ -466,6 +466,36 @@ void ODRHash::AddCXXRecordDecl(cons<wbr>t CXX<br>   }<br> }<br><br>+void ODRHash::AddFunctionDecl(const FunctionDecl *Function) {<br>+  assert(Function && "Expecting non-null pointer.");<br>+<br>+  // Skip hashing these kinds of function.<br>+  if (Function->isImplicit()) return;<br>+  if (Function->isDefaulted()) return;<br>+  if (Function->isDeleted()) return;<br>+  if (!Function->hasBody()) return;<br>+  if (!Function->getBody()) return;<br>+<br>+  // Skip functions that are specializations or in specialization context.<br>+  const DeclContext *DC = Function;<br>+  while (DC) {<br>+    if (isa<ClassTemplateSpecializati<wbr>onDecl>(DC)) return;<br>+    if (auto *F = dyn_cast<FunctionDecl>(DC))<br>+      if (F->isFunctionTemplateSpeciali<wbr>zation()) return;<br>+    DC = DC->getParent();<br>+  }<br>+<br>+  AddDecl(Function);<br>+<br>+  AddQualType(Function->getRetu<wbr>rnType());<br>+<br>+  ID.AddInteger(Function->param<wbr>_size());<br>+  for (auto Param : Function->parameters())<br>+    AddSubDecl(Param);<br>+<br>+  AddStmt(Function->getBody());<br>+}<br>+<br> void ODRHash::AddDecl(const Decl *D) {<br>   assert(D && "Expecting non-null pointer.");<br>   D = D->getCanonicalDecl();<br><br>Modified: cfe/trunk/lib/Serialization/AS<wbr>TReader.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=321395&r1=321394&r2=321395&view=diff" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/Serializat<wbr>ion/ASTReader.cpp?rev=321395&<wbr>r1=321394&r2=321395&view=diff</a><br>==============================<wbr>==============================<wbr>==================<br>--- cfe/trunk/lib/Serialization/AS<wbr>TReader.cpp (original)<br>+++ cfe/trunk/lib/Serialization/AS<wbr>TReader.cpp Fri Dec 22 16:41:01 2017<br>@@ -9235,8 +9235,16 @@ void ASTReader::finishPendingAction<wbr>s() {<br>       const FunctionDecl *Defn = nullptr;<br>       if (!getContext().getLangOpts().M<wbr>odules || !FD->hasBody(Defn)) {<br>         FD->setLazyBody(PB->se<wbr>cond);<br>-      } else<br>-        mergeDefinitionVisibili<wbr>ty(const_cast<FunctionDecl*>(D<wbr>efn), FD);<br>+      } else {<br>+        auto *NonConstDefn = const_cast<FunctionDecl*>(Defn<wbr>);<br>+        mergeDefinitionVisibili<wbr>ty(NonConstDefn, FD);<br>+<br>+        if (!FD->isLateTemplateParsed() &&<br>+            !NonConstDefn->isLa<wbr>teTemplateParsed() &&<br>+            FD->getODRHash() != NonConstDefn->getODRHash()) {<br>+          PendingFunctionOdrMer<wbr>geFailures[FD].push_back(<wbr>NonConstDefn);<br>+        }<br>+      }<br>       continue;<br>     }<br><br>@@ -9253,7 +9261,8 @@ void ASTReader::finishPendingAction<wbr>s() {<br> }<br><br> void ASTReader::diagnoseOdrViolatio<wbr>ns() {<br>-  if (PendingOdrMergeFailures.empty<wbr>() && PendingOdrMergeChecks.empty())<br>+  if (PendingOdrMergeFailures.empty<wbr>() && PendingOdrMergeChecks.empty() &&<br>+      PendingFunctionOdrMergeFa<wbr>ilures.empty())<br>     return;<br><br>   // Trigger the import of the full definition of each class that had any<br>@@ -9275,6 +9284,20 @@ void ASTReader::diagnoseOdrViolatio<wbr>ns()<br>     }<br>   }<br><br>+  // Trigger the import of functions.<br>+  auto FunctionOdrMergeFailures = std::move(PendingFunctionOdrMe<wbr>rgeFailures);<br>+  PendingFunctionOdrMergeFailur<wbr>es.clear();<br>+  for (auto &Merge : FunctionOdrMergeFailures) {<br>+    Merge.first->buildLookup();<br>+    Merge.first->decls_begin();<br>+    Merge.first->getBody();<br>+    for (auto &FD : Merge.second) {<br>+      FD->buildLookup();<br>+      FD->decls_begin();<br>+      FD->getBody();<br>+    }<br>+  }<br>+<br>   // For each declaration from a merged context, check that the canonical<br>   // definition of that context also contains a declaration of the same<br>   // entity.<br>@@ -9357,13 +9380,35 @@ void ASTReader::diagnoseOdrViolatio<wbr>ns()<br>     }<br>   }<br><br>-  if (OdrMergeFailures.empty())<br>+  if (OdrMergeFailures.empty() && FunctionOdrMergeFailures.empty<wbr>())<br>     return;<br><br>   // Ensure we don't accidentally recursively enter deserialization while<br>   // we're producing our diagnostics.<br>   Deserializing RecursionGuard(this);<br><br>+  // Common code for hashing helpers.<br>+  ODRHash Hash;<br>+  auto ComputeQualTypeODRHash = [&Hash](QualType Ty) {<br>+    Hash.clear();<br>+    Hash.AddQualType(Ty);<br>+    return Hash.CalculateHash();<br>+  };<br>+<br>+  auto ComputeODRHash = [&Hash](const Stmt *S) {<br>+    assert(S);<br>+    Hash.clear();<br>+    Hash.AddStmt(S);<br>+    return Hash.CalculateHash();<br>+  };<br>+<br>+  auto ComputeSubDeclODRHash = [&Hash](const Decl *D) {<br>+    assert(D);<br>+    Hash.clear();<br>+    Hash.AddSubDecl(D);<br>+    return Hash.CalculateHash();<br>+  };<br>+<br>   // Issue any pending ODR-failure diagnostics.<br>   for (auto &Merge : OdrMergeFailures) {<br>     // If we've already pointed out a specific problem with this class, don't<br>@@ -9411,13 +9456,6 @@ void ASTReader::diagnoseOdrViolatio<wbr>ns()<br>                  << SecondModule << Range << DiffType;<br>         };<br><br>-        ODRHash Hash;<br>-        auto ComputeQualTypeODRHash = [&Hash](QualType Ty) {<br>-          Hash.clear();<br>-          Hash.AddQualType(Ty);<br>-          return Hash.CalculateHash();<br>-        };<br>-<br>         unsigned FirstNumBases = FirstDD->NumBases;<br>         unsigned FirstNumVBases = FirstDD->NumVBases;<br>         unsigned SecondNumBases = SecondDD->NumBases;<br>@@ -9520,14 +9558,12 @@ void ASTReader::diagnoseOdrViolatio<wbr>ns()<br>       if (FirstTemplate && SecondTemplate) {<br>         DeclHashes FirstTemplateHashes;<br>         DeclHashes SecondTemplateHashes;<br>-        ODRHash Hash;<br><br>         auto PopulateTemplateParameterHashs =<br>-            [&Hash](DeclHashes &Hashes, const ClassTemplateDecl *TD) {<br>+            [&ComputeSubDeclODR<wbr>Hash](DeclHashes &Hashes,<br>+                               <wbr>      const ClassTemplateDecl *TD) {<br>               for (auto *D : TD->getTemplateParameters()->a<wbr>sArray()) {<br>-                Hash.clear();<br>-                Hash.AddSubDecl<wbr>(D);<br>-                Hashes.emplace_<wbr>back(D, Hash.CalculateHash());<br>+                Hashes.emplace_<wbr>back(D, ComputeSubDeclODRHash(D));<br>               }<br>             };<br><br>@@ -9696,18 +9732,15 @@ void ASTReader::diagnoseOdrViolatio<wbr>ns()<br><br>       DeclHashes FirstHashes;<br>       DeclHashes SecondHashes;<br>-      ODRHash Hash;<br><br>-      auto PopulateHashes = [&Hash, FirstRecord](DeclHashes &Hashes,<br>-                               <wbr>                  CXXRecordDec<wbr>l *Record) {<br>+      auto PopulateHashes = [&ComputeSubDeclODRHash, FirstRecord](<br>+                               <wbr> DeclHashes &Hashes, CXXRecordDecl *Record) {<br>         for (auto *D : Record->decls()) {<br>           // Due to decl merging, the first CXXRecordDecl is the parent of<br>           // Decls in both records.<br>           if (!ODRHash::isWhitelistedDecl(D<wbr>, FirstRecord))<br>             continue;<br>-          Hash.clear();<br>-          Hash.AddSubDecl(D);<br>-          Hashes.emplace_back(D<wbr>, Hash.CalculateHash());<br>+          Hashes.emplace_back(D<wbr>, ComputeSubDeclODRHash(D));<br>         }<br>       };<br>       PopulateHashes(FirstHash<wbr>es, FirstRecord);<br>@@ -9901,19 +9934,6 @@ void ASTReader::diagnoseOdrViolatio<wbr>ns()<br>                << SecondModule << Range << DiffType;<br>       };<br><br>-      auto ComputeODRHash = [&Hash](const Stmt* S) {<br>-        assert(S);<br>-        Hash.clear();<br>-        Hash.AddStmt(S);<br>-        return Hash.CalculateHash();<br>-      };<br>-<br>-      auto ComputeQualTypeODRHash = [&Hash](QualType Ty) {<br>-        Hash.clear();<br>-        Hash.AddQualType(Ty);<br>-        return Hash.CalculateHash();<br>-      };<br>-<br>       switch (FirstDiffType) {<br>       case Other:<br>       case EndOfClass:<br>@@ -10488,6 +10508,160 @@ void ASTReader::diagnoseOdrViolatio<wbr>ns()<br>         << Merge.first;<br>     }<br>   }<br>+<br>+  // Issue ODR failures diagnostics for functions.<br>+  for (auto &Merge : FunctionOdrMergeFailures) {<br>+    enum ODRFunctionDifference {<br>+      ReturnType,<br>+      ParameterName,<br>+      ParameterType,<br>+      ParameterSingleDefaultArg<wbr>ument,<br>+      ParameterDifferentDefault<wbr>Argument,<br>+      FunctionBody,<br>+    };<br>+<br>+    FunctionDecl *FirstFunction = Merge.first;<br>+    std::string FirstModule = getOwningModuleNameForDiagnost<wbr>ic(FirstFunction);<br>+<br>+    bool Diagnosed = false;<br>+    for (auto &SecondFunction : Merge.second) {<br>+<br>+      if (FirstFunction == SecondFunction)<br>+        continue;<br>+<br>+      std::string SecondModule =<br>+          getOwningModuleNameFo<wbr>rDiagnostic(SecondFunction);<br>+<br>+      auto ODRDiagError = [FirstFunction, &FirstModule,<br>+                           this<wbr>](SourceLocation Loc, SourceRange Range,<br>+                               <wbr>  ODRFunctionDifference DiffType) {<br>+        return Diag(Loc, diag::err_module_odr_violation<wbr>_function)<br>+               << FirstFunction << FirstModule.empty() << FirstModule << Range<br>+               << DiffType;<br>+      };<br>+      auto ODRDiagNote = [&SecondModule, this](SourceLocation Loc,<br>+                               <wbr>                SourceRange Range,<br>+                               <wbr>                ODRFunctionDif<wbr>ference DiffType) {<br>+        return Diag(Loc, diag::note_module_odr_violatio<wbr>n_function)<br>+               << SecondModule << Range << DiffType;<br>+      };<br>+<br>+      if (ComputeQualTypeODRHash(FirstF<wbr>unction->getReturnType()) !=<br>+          ComputeQualTypeODRHas<wbr>h(SecondFunction-><wbr>getReturnType())) {<br>+        ODRDiagError(FirstFunct<wbr>ion->getReturnTypeSourceRange(<wbr>).getBegin(),<br>+                     FirstFunct<wbr>ion->getReturnTypeSourceRange(<wbr>), ReturnType)<br>+            << FirstFunction->getReturnType()<wbr>;<br>+        ODRDiagNote(SecondFunct<wbr>ion->getReturnTypeSourceRange(<wbr>).getBegin(),<br>+                    SecondFunct<wbr>ion->getReturnTypeSourceRange(<wbr>), ReturnType)<br>+            << SecondFunction->getReturnType(<wbr>);<br>+        Diagnosed = true;<br>+        break;<br>+      }<br>+<br>+      assert(FirstFunction->par<wbr>am_size() == SecondFunction->param_size() &&<br>+             "Merged functions with different number of parameters");<br>+<br>+      auto ParamSize = FirstFunction->param_size();<br>+      bool ParameterMismatch = false;<br>+      for (unsigned I = 0; I < ParamSize; ++I) {<br>+        auto *FirstParam = FirstFunction->getParamDecl(I)<wbr>;<br>+        auto *SecondParam = SecondFunction->getParamDecl(I<wbr>);<br>+<br>+        assert(getContext().has<wbr>SameType(FirstParam->getType()<wbr>,<br>+                               <wbr>       SecondParam->getType()) &&<br>+               "Merged function has different parameter types.");<br>+<br>+        if (FirstParam->getDeclName() != SecondParam->getDeclName()) {<br>+          ODRDiagError(FirstPar<wbr>am->getLocation(), FirstParam->getSourceRange(),<br>+                       Paramete<wbr>rName)<br>+              << I + 1 << FirstParam->getDeclName();<br>+          ODRDiagNote(SecondPar<wbr>am->getLocation(), SecondParam->getSourceRange(),<br>+                      Parameter<wbr>Name)<br>+              << I + 1 << SecondParam->getDeclName();<br>+          ParameterMismatch = true;<br>+          break;<br>+        };<br>+<br>+        QualType FirstParamType = FirstParam->getType();<br>+        QualType SecondParamType = SecondParam->getType();<br>+        if (FirstParamType != SecondParamType &&<br>+            ComputeQualTypeODRH<wbr>ash(FirstParamType) !=<br>+                ComputeQualType<wbr>ODRHash(SecondParamType)) {<br>+          if (const DecayedType *ParamDecayedType =<br>+                  FirstParamTyp<wbr>e->getAs<DecayedType>()) {<br>+            ODRDiagError(FirstP<wbr>aram->getLocation(),<br>+                         FirstP<wbr>aram->getSourceRange(), ParameterType)<br>+                << (I + 1) << FirstParamType << true<br>+                << ParamDecayedType->getOriginalT<wbr>ype();<br>+          } else {<br>+            ODRDiagError(FirstP<wbr>aram->getLocation(),<br>+                         FirstP<wbr>aram->getSourceRange(), ParameterType)<br>+                << (I + 1) << FirstParamType << false;<br>+          }<br>+<br>+          if (const DecayedType *ParamDecayedType =<br>+                  SecondParamTy<wbr>pe->getAs<DecayedType>()) {<br>+            ODRDiagNote(SecondP<wbr>aram->getLocation(),<br>+                        SecondP<wbr>aram->getSourceRange(), ParameterType)<br>+                << (I + 1) << SecondParamType << true<br>+                << ParamDecayedType->getOriginalT<wbr>ype();<br>+          } else {<br>+            ODRDiagNote(SecondP<wbr>aram->getLocation(),<br>+                        SecondP<wbr>aram->getSourceRange(), ParameterType)<br>+                << (I + 1) << SecondParamType << false;<br>+          }<br>+          ParameterMismatch = true;<br>+          break;<br>+        }<br>+<br>+        const Expr *FirstInit = FirstParam->getInit();<br>+        const Expr *SecondInit = SecondParam->getInit();<br>+        if ((FirstInit == nullptr) != (SecondInit == nullptr)) {<br>+          ODRDiagError(FirstPar<wbr>am->getLocation(), FirstParam->getSourceRange(),<br>+                       Paramete<wbr>rSingleDefaultArgument)<br>+              << (I + 1) << (FirstInit == nullptr)<br>+              << (FirstInit ? FirstInit->getSourceRange() : SourceRange());<br>+          ODRDiagNote(SecondPar<wbr>am->getLocation(), SecondParam->getSourceRange(),<br>+                      Parameter<wbr>SingleDefaultArgument)<br>+              << (I + 1) << (SecondInit == nullptr)<br>+              << (SecondInit ? SecondInit->getSourceRange() : SourceRange());<br>+          ParameterMismatch = true;<br>+          break;<br>+        }<br>+<br>+        if (FirstInit && SecondInit &&<br>+            ComputeODRHash(Firs<wbr>tInit) != ComputeODRHash(SecondInit)) {<br>+          ODRDiagError(FirstPar<wbr>am->getLocation(), FirstParam->getSourceRange(),<br>+                       Paramete<wbr>rDifferentDefaultArgument)<br>+              << (I + 1) << FirstInit->getSourceRange();<br>+          ODRDiagNote(SecondPar<wbr>am->getLocation(), SecondParam->getSourceRange(),<br>+                      Parameter<wbr>DifferentDefaultArgument)<br>+              << (I + 1) << SecondInit->getSourceRange();<br>+          ParameterMismatch = true;<br>+          break;<br>+        }<br>+<br>+        assert(ComputeSubDeclOD<wbr>RHash(FirstParam) ==<br>+                   ComputeSubDe<wbr>clODRHash(SecondParam) &&<br>+               "Undiagnosed parameter difference.");<br>+      }<br>+<br>+      if (ParameterMismatch) {<br>+        Diagnosed = true;<br>+        break;<br>+      }<br>+<br>+      // If no error has been generated before now, assume the problem is in<br>+      // the body and generate a message.<br>+      ODRDiagError(FirstFunctio<wbr>n->getLocation(),<br>+                   FirstFunctio<wbr>n->getSourceRange(), FunctionBody);<br>+      ODRDiagNote(SecondFunctio<wbr>n->getLocation(),<br>+                  SecondFunctio<wbr>n->getSourceRange(), FunctionBody);<br>+      Diagnosed = true;<br>+      break;<br>+    }<br>+    assert(Diagnosed && "Unable to emit ODR diagnostic.");<br>+  }<br> }<br><br> void ASTReader::StartedDeserializin<wbr>g() {<br><br>Modified: cfe/trunk/lib/Serialization/AS<wbr>TReaderDecl.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=321395&r1=321394&r2=321395&view=diff" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/Serializat<wbr>ion/ASTReaderDecl.cpp?rev=<wbr>321395&r1=321394&r2=321395&<wbr>view=diff</a><br>==============================<wbr>==============================<wbr>==================<br>--- cfe/trunk/lib/Serialization/AS<wbr>TReaderDecl.cpp (original)<br>+++ cfe/trunk/lib/Serialization/AS<wbr>TReaderDecl.cpp Fri Dec 22 16:41:01 2017<br>@@ -796,6 +796,9 @@ void ASTDeclReader::VisitFunctionDe<wbr>cl(Fu<br>   FD->setCachedLinkage(Linkage<wbr>(Record.readInt()));<br>   FD->EndRangeLoc = ReadSourceLocation();<br><br>+  FD->ODRHash = Record.readInt();<br>+  FD->HasODRHash = true;<br>+<br>   switch ((FunctionDecl::TemplatedKind)<wbr>Record.readInt()) {<br>   case FunctionDecl::TK_NonTemplate:<br>     mergeRedeclarable(FD, Redecl);<br><br>Modified: cfe/trunk/lib/Serialization/AS<wbr>TWriterDecl.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=321395&r1=321394&r2=321395&view=diff" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/lib/Serializat<wbr>ion/ASTWriterDecl.cpp?rev=<wbr>321395&r1=321394&r2=321395&<wbr>view=diff</a><br>==============================<wbr>==============================<wbr>==================<br>--- cfe/trunk/lib/Serialization/AS<wbr>TWriterDecl.cpp (original)<br>+++ cfe/trunk/lib/Serialization/AS<wbr>TWriterDecl.cpp Fri Dec 22 16:41:01 2017<br>@@ -538,6 +538,8 @@ void ASTDeclWriter::VisitFunctionDe<wbr>cl(Fu<br>   Record.push_back(D->getLinka<wbr>geInternal());<br>   Record.AddSourceLocation(D-><wbr>getLocEnd());<br><br>+  Record.push_back(D->getODRHas<wbr>h());<br>+<br>   Record.push_back(D->getTempl<wbr>atedKind());<br>   switch (D->getTemplatedKind()) {<br>   case FunctionDecl::TK_NonTemplate:<br>@@ -2072,6 +2074,7 @@ void ASTWriter::WriteDeclAbbrevs() {<br>   Abv->Add(BitCodeAbbrevOp(Bit<wbr>CodeAbbrevOp::Fixed, 1)); // LateParsed<br>   Abv->Add(BitCodeAbbrevOp(Bit<wbr>CodeAbbrevOp::Fixed, 3)); // Linkage<br>   Abv->Add(BitCodeAbbrevOp(Bit<wbr>CodeAbbrevOp::VBR, 6));   // LocEnd<br>+  Abv->Add(BitCodeAbbrevOp(BitC<wbr>odeAbbrevOp::Fixed, 32)); // ODRHash<br>   Abv->Add(BitCodeAbbrevOp(Bit<wbr>CodeAbbrevOp::Fixed, 3)); // TemplateKind<br>   // This Array slurps the rest of the record. Fortunately we want to encode<br>   // (nearly) all the remaining (variable number of) fields in the same way.<br><br>Modified: cfe/trunk/test/Modules/odr_has<wbr>h.cpp<br>URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash.cpp?rev=321395&r1=321394&r2=321395&view=diff" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/cfe/trunk/test/Modules/<wbr>odr_hash.cpp?rev=321395&r1=<wbr>321394&r2=321395&view=diff</a><br>==============================<wbr>==============================<wbr>==================<br>--- cfe/trunk/test/Modules/odr_has<wbr>h.cpp (original)<br>+++ cfe/trunk/test/Modules/odr_has<wbr>h.cpp Fri Dec 22 16:41:01 2017<br>@@ -557,11 +557,11 @@ S10 s10;<br><br> #if defined(FIRST)<br> struct S11 {<br>-  void A(int x) {}<br>+  void A(int x);<br> };<br> #elif defined(SECOND)<br> struct S11 {<br>-  void A(int y) {}<br>+  void A(int y);<br> };<br> #else<br> S11 s11;<br>@@ -571,11 +571,11 @@ S11 s11;<br><br> #if defined(FIRST)<br> struct S12 {<br>-  void A(int x) {}<br>+  void A(int x);<br> };<br> #elif defined(SECOND)<br> struct S12 {<br>-  void A(int x = 1) {}<br>+  void A(int x = 1);<br> };<br> #else<br> S12 s12;<br>@@ -585,11 +585,11 @@ S12 s12;<br><br> #if defined(FIRST)<br> struct S13 {<br>-  void A(int x = 1 + 0) {}<br>+  void A(int x = 1 + 0);<br> };<br> #elif defined(SECOND)<br> struct S13 {<br>-  void A(int x = 1) {}<br>+  void A(int x = 1);<br> };<br> #else<br> S13 s13;<br>@@ -599,11 +599,11 @@ S13 s13;<br><br> #if defined(FIRST)<br> struct S14 {<br>-  void A(int x[2]) {}<br>+  void A(int x[2]);<br> };<br> #elif defined(SECOND)<br> struct S14 {<br>-  void A(int x[3]) {}<br>+  void A(int x[3]);<br> };<br> #else<br> S14 s14;<br>@@ -2751,14 +2751,14 @@ namespace DefaultArguments {<br> template <typename T><br> struct S {<br>   struct R {<br>-    void foo(T x = 0) {}<br>+    void foo(T x = 0);<br>   };<br> };<br> #elif defined(SECOND)<br> template <typename T><br> struct S {<br>   struct R {<br>-    void foo(T x = 1) {}<br>+    void foo(T x = 1);<br>   };<br> };<br> #else<br>@@ -2771,13 +2771,13 @@ void run() {<br><br> #if defined(FIRST)<br> template <typename alpha> struct Bravo {<br>-  void charlie(bool delta = false) {}<br>+  void charlie(bool delta = false);<br> };<br> typedef Bravo<char> echo;<br> echo foxtrot;<br> #elif defined(SECOND)<br> template <typename alpha> struct Bravo {<br>-  void charlie(bool delta = (false)) {}<br>+  void charlie(bool delta = (false));<br> };<br> typedef Bravo<char> echo;<br> echo foxtrot;<br>@@ -2788,6 +2788,142 @@ Bravo<char> golf;<br> #endif<br> }  // namespace DefaultArguments<br><br>+namespace FunctionDecl {<br>+#if defined(FIRST)<br>+struct S1 {};<br>+S1 s1a;<br>+#elif defined(SECOND)<br>+struct S1 {};<br>+#else<br>+S1 s1;<br>+#endif<br>+<br>+#if defined(FIRST)<br>+struct S2 {<br>+  S2() = default;<br>+};<br>+S2 s2a = S2();<br>+#elif defined(SECOND)<br>+struct S2 {<br>+  S2() = default;<br>+};<br>+#else<br>+S2 s2;<br>+#endif<br>+<br>+#if defined(FIRST)<br>+struct S3 {<br>+  S3() = delete;<br>+};<br>+S3* s3c;<br>+#elif defined(SECOND)<br>+struct S3 {<br>+  S3() = delete;<br>+};<br>+#else<br>+S3* s3;<br>+#endif<br>+<br>+#if defined(FIRST) || defined(SECOND)<br>+int F1(int x, float y = 2.7) { return 1; }<br>+#else<br>+int I1 = F1(1);<br>+#endif<br>+<br>+#if defined(FIRST)<br>+int F2() { return 1; }<br>+#elif defined(SECOND)<br>+double F2() { return 1; }<br>+#else<br>+int I2 = F2();<br>+// expected-error@-1 {{call to 'F2' is ambiguous}}<br>+// <a href="mailto:expected-note@first.h" target="_blank">expected-note@first.h</a>:* {{candidate function}}<br>+// <a href="mailto:expected-note@second.h" target="_blank">expected-note@second.h</a>:* {{candidate function}}<br>+#endif<br>+<br>+#if defined(FIRST)<br>+int F3(float) { return 1; }<br>+#elif defined(SECOND)<br>+int F3(double) { return 1; }<br>+#else<br>+int I3 = F3(1);<br>+// expected-error@-1 {{call to 'F3' is ambiguous}}<br>+// <a href="mailto:expected-note@first.h" target="_blank">expected-note@first.h</a>:* {{candidate function}}<br>+// <a href="mailto:expected-note@second.h" target="_blank">expected-note@second.h</a>:* {{candidate function}}<br>+#endif<br>+<br>+#if defined(FIRST)<br>+int F4(int x) { return 1; }<br>+#elif defined(SECOND)<br>+int F4(int y) { return 1; }<br>+#else<br>+int I4 = F4(1);<br>+// <a href="mailto:expected-error@second.h" target="_blank">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>+// <a href="mailto:expected-note@first.h" target="_blank">expected-note@first.h</a>:* {{but in 'FirstModule' found 1st parameter with name 'x'}}<br>+#endif<br>+<br>+#if defined(FIRST)<br>+int F5(int x) { return 1; }<br>+#elif defined(SECOND)<br>+int F5(int x = 1) { return 1; }<br>+#else<br>+int I5 = F6(1);<br>+// <a href="mailto:expected-error@second.h" target="_blank">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>+// <a href="mailto:expected-note@first.h" target="_blank">expected-note@first.h</a>:* {{but in 'FirstModule' found 1st parameter with a default argument}}<br>+#endif<br>+<br>+#if defined(FIRST)<br>+int F6(int x = 2) { return 1; }<br>+#elif defined(SECOND)<br>+int F6(int x = 1) { return 1; }<br>+#else<br>+int I6 = F6(1);<br>+// <a href="mailto:expected-error@second.h" target="_blank">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>+// <a href="mailto:expected-note@first.h" target="_blank">expected-note@first.h</a>:* {{but in 'FirstModule' found 1st parameter with a different default argument}}<br>+#endif<br>+<br>+using I = int;<br>+#if defined(FIRST)<br>+I F7() { return 0; }<br>+#elif defined(SECOND)<br>+int F7() { return 0; }<br>+#else<br>+int I7 = F7();<br>+// <a href="mailto:expected-error@second.h" target="_blank">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>+// <a href="mailto:expected-note@first.h" target="_blank">expected-note@first.h</a>:* {{but in 'FirstModule' found different return type 'FunctionDecl::I' (aka 'int')}}<br>+#endif<br>+<br>+#if defined(FIRST)<br>+int F8(int) { return 0; }<br>+#elif defined(SECOND)<br>+int F8(I) { return 0; }<br>+#else<br>+int I8 = F8(1);<br>+// <a href="mailto:expected-error@second.h" target="_blank">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>+// <a href="mailto:expected-note@first.h" target="_blank">expected-note@first.h</a>:* {{but in 'FirstModule' found 1st parameter with type 'int'}}<br>+#endif<br>+<br>+#if defined(FIRST)<br>+int F9(int[1]) { return 0; }<br>+#elif defined(SECOND)<br>+int F9(int[2]) { return 0; }<br>+#else<br>+int I9 = F9(nullptr);<br>+// <a href="mailto:expected-error@second.h" target="_blank">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>+// <a href="mailto:expected-note@first.h" target="_blank">expected-note@first.h</a>:* {{but in 'FirstModule' found 1st parameter with type 'int *' decayed from 'int [1]'}}<br>+#endif<br>+<br>+#if defined(FIRST)<br>+int F10() { return 1; }<br>+#elif defined(SECOND)<br>+int F10() { return 2; }<br>+#else<br>+int I10 = F10();<br>+#endif<br>+// <a href="mailto:expected-error@second.h" target="_blank">expected-error@second.h</a>:* {{'FunctionDecl::F10' has different definitions in different modules; definition in module 'SecondModule' first difference is function body}}<br>+// <a href="mailto:expected-note@first.h" target="_blank">expected-note@first.h</a>:* {{but in 'FirstModule' found a different body}}<br>+}  // namespace FunctionDecl<br>+<br> // Keep macros contained to one file.<br> #ifdef FIRST<br> #undef FIRST<br><br><br>______________________________<wbr>_________________<br>cfe-commits mailing list<br><a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br></div></div></blockquote></div><br></div></div></div></div></div></blockquote></div><br></div></blockquote></div><br></div></div></div></div></div>
<br>______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
<br></blockquote></div><br></div>