title: [[deprecated]] + __attribute__ ((visibility ("default"))) in GCC 6.2
body: <p>Combining the <code>[[deprecated]]</code> and the <code>__attribute__ ((visibility ("default")))</code> attributes with <code>-std=c++14</code> generate errors (different depending on the order used <code>expected identifier before ‘__attribute__’</code> or <code>expected identifier before ‘[’ token</code>).
  Using them separately does not generate the errors.</p>
  
  <p>The c++11 style attribute <code>[[gnu::visibility("default")]]</code> works for classes, but not for functions (the code compiles, but produces a <code>-Wattributes</code> warning and the symbol is left out when built with <code>-fvisibility=hidden</code>).</p>
  
  <p>Is this a bug in the compiler (I used GCC 6.2 for these tests) or something specified by c++ standard? The same code (<code>[[deprecated]] __attribute__ ((visibility ("default")))</code>) works as expected using clang).</p>
  
  <p>This is the code I used for my tests to combine all the possibilities, the only cases that produce the wanted result (deprecated + default visibility) are 3 and 7, i.e. the ones using the old style attributes.</p>
  
  <p><code>foo.h</code></p>
  
  <pre><code>#if defined(X_VERSION)
  #  if (X_VERSION % 4) == 0        //  0   4   8  12
  #    define DEPRECATED [[deprecated]]
  #    define VISIBILITY [[gnu::visibility("default")]]
  #  elif (X_VERSION % 4) == 1      //  1   5   9  13
  #    define DEPRECATED [[deprecated]]
  #    define VISIBILITY __attribute__ ((visibility ("default")))
  #  elif (X_VERSION % 4) == 2      //  2   6  10  14
  #    define DEPRECATED __attribute__((__deprecated__))
  #    define VISIBILITY [[gnu::visibility("default")]]
  #  elif (X_VERSION % 4) == 3      //  3   7  11  15
  #    define DEPRECATED __attribute__((__deprecated__))
  #    define VISIBILITY __attribute__ ((visibility ("default")))
  #  else
  #    error "Invalid X_VERSION"
  #  endif
  
  #  if (X_VERSION / 4) == 0        //  0   1   2   3
  #    define DEPRECATED_API DEPRECATED VISIBILITY
  #  elif (X_VERSION / 4) == 1      //  4   5   6   7
  #    define DEPRECATED_API VISIBILITY DEPRECATED
  #  elif (X_VERSION / 4) == 2      //  8   9  10  11
  #    define DEPRECATED_API DEPRECATED
  #  elif (X_VERSION / 4) == 3      // 12  13  14  15
  #    define DEPRECATED_API VISIBILITY
  #  else
  #    error "Invalid X_VERSION"
  #  endif
  #else
  #  error "X_VERSION not defined"
  #endif
  
  #if defined(DEPRECATED_API)
  #  define XSTR(x) STR(x)
  #  define STR(x) #x
  #  pragma message "DEPRECATED_API = " XSTR(DEPRECATED_API)
  #endif
  
  class DEPRECATED_API foo
  {
  public:
      foo();
      virtual ~foo();
      void test();
  
      int a;
  };
  
  void DEPRECATED_API a_function();
  </code></pre>
  
  <p><code>foo.cpp</code></p>
  
  <pre><code>#include &lt;foo.h&gt;
  
  foo::foo() {}
  foo::~foo() {}
  void foo::test() {}
  
  void a_function() {}
  </code></pre>
  
  <p><code>CMakeLists.txt</code></p>
  
  <pre><code>cmake_minimum_required(VERSION 3.6)
  project(test_lib)
  
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
  set(CMAKE_INCLUDE_CURRENT_DIR ON)
  
  
  foreach(i RANGE 0 15)
    if(i LESS 10)
      set(target_name foo_v0${i})
    else()
      set(target_name foo_v${i})
    endif()
    add_library(${target_name} SHARED foo.cpp foo.h)
    target_compile_definitions(${target_name} PRIVATE X_VERSION=${i})
  endforeach()
  </code></pre>