LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 26179 - Fails to merge templated static member variables
Summary: Fails to merge templated static member variables
Status: RESOLVED FIXED
Alias: None
Product: clang
Classification: Unclassified
Component: Modules (show other bugs)
Version: trunk
Hardware: PC All
: P normal
Assignee: Unassigned Clang Bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-01-16 16:35 PST by Vassil Vassilev
Modified: 2016-01-24 16:26 PST (History)
4 users (show)

See Also:
Fixed By Commit(s):


Attachments
Reproducer (2.45 KB, application/octet-stream)
2016-01-16 16:49 PST, Vassil Vassilev
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Vassil Vassilev 2016-01-16 16:35:53 PST
My diagnosis is:
template<typename T> struct basic_string {
  static T _S_empty_rep_storage[]; // #1
};
template<typename T> T basic_string<T>::_S_empty_rep_storage[sizeof(T)]; // #2

#1 and #2 end up on the same redecl chain. #2 gets registered in the lookup table and when isSameEntity compares the type of the imported VarDecl (essentially #1 coming from another module) it finds a mismatch.

A fix to this issue is just dialing Existing->getCanonicalDecl. There are two questions I cannot answer (yet?):
  1. Should #2 really end up in the redecl chain, it looks like a different decl (at least when it comes to types, true that both are IncompleteArrayTypes]?
  2. Why #2 ended up in the lookup table when #1 was seen before?
    3. Where should the fix go:
      a) should it be isSameEntity(Existing->getCanonicalDecl(), D) - semantically #2 cannot end up as a canonical decl.
      b) should I extend the logic (somehow) of isSameEntity (VarDecl section)?




   2872	    DeclContext::lookup_result R = MergeDC->noload_lookup(Name);
   2873	    for (DeclContext::lookup_iterator I = R.begin(), E = R.end(); I != E; ++I) {
   2874	      if (NamedDecl *Existing = getDeclForMerging(*I, TypedefNameForLinkage))
-> 2875	        if (isSameEntity(Existing, D))
   2876	          return FindExistingResult(Reader, D, Existing, AnonymousDeclNumber,
   2877	                                    TypedefNameForLinkage);
   2878	    }
(lldb) p Existing
(clang::VarDecl *) $186 = 0x000000010c831390
(lldb) p Existing->dump()
VarDecl 0x10c831390 parent 0x10c051530 prev 0x10c830fa8 </Users/vvassilev/workspace/llvm-git/src/tools/clang/test/Modules/Inputs/PRN/basic_string.h:9:1, line:10:50> col:20 _S_empty_rep_storage 'T [sizeof(T)]'
(lldb) p Existing->getPreviousDecl()
(clang::VarDecl *) $187 = 0x000000010c830fa8
(lldb) p Existing->getPreviousDecl()->dump()
VarDecl 0x10c830fa8 </Users/vvassilev/workspace/llvm-git/src/tools/clang/test/Modules/Inputs/PRN/basic_string.h:6:3, col:33> col:12 _S_empty_rep_storage 'T []' static
(lldb) p Existing->getPreviousDecl()->getPreviousDecl()
(clang::Decl *) $188 = 0x0000000000000000
(lldb) p Existing->getMostRecentDecl()
(clang::VarDecl *) $189 = 0x000000010c831390
(lldb) p Existing->getCanonicalDecl()
(clang::VarDecl *) $190 = 0x000000010c830fa8
(lldb) p Existing->getCanonicalDecl()->dump()
VarDecl 0x10c830fa8 </Users/vvassilev/workspace/llvm-git/src/tools/clang/test/Modules/Inputs/PRN/basic_string.h:6:3, col:33> col:12 _S_empty_rep_storage 'T []' static

The error message is:

In module 'B' imported from /Users/vvassilev/workspace/llvm-git/src/tools/clang/test/Modules/Inputs/PRN/A.h:5:
/Users/vvassilev/workspace/llvm-git/src/tools/clang/test/Modules/Inputs/PRN/basic_string.h:6:12: error: 'basic_string::_S_empty_rep_storage' from module 'B' is not present in definition of 'basic_string<T>' provided earlier
  static T _S_empty_rep_storage[];
           ^
/Users/vvassilev/workspace/llvm-git/src/tools/clang/test/Modules/Inputs/PRN/basic_string.h:6:12: note: declaration of '_S_empty_rep_storage' does not match
  static T _S_empty_rep_storage[];
           ^
/Users/vvassilev/workspace/llvm-git/src/tools/clang/test/Modules/prN.cpp:5:10: fatal error: could not build module 'A'
#include "A.h"
 ~~~~~~~~^~~~~
2 errors generated.
Comment 1 Vassil Vassilev 2016-01-16 16:49:55 PST
Created attachment 15645 [details]
Reproducer
Comment 2 Vassil Vassilev 2016-01-24 16:26:23 PST
Fixed in r258524.