SlideShare a Scribd company logo
1 of 49
Going Native Highlights
Introduction to Variadic Templates.
          Clang overview.
Variadic Templates

• Fundamentals
• Usage
• Samples




             Quickoffice Proprietary and Confidential - Not for Disclosure   2
Fundamentals

Class declaration:


template<typename... Ts>
class A
{
};


Function declaration:


template<typename... Ts>
voidfoo(const Ts&... vs)
{
}
                        Quickoffice Proprietary and Confidential - Not for Disclosure   3
What is Ts and vs?

• Ts is an alias for a list of types
• vs is an alias for a list of values


typedef Ts MyList; // error!
Ts var;// error!
auto copy = vs;// error!




                     Quickoffice Proprietary and Confidential - Not for Disclosure   4
Parameters Packs Usage

• Get pack size


size_t items = sizeof...(Ts); // or vs


• Expand back


template<typename... Ts>
voidfoo(const Ts&... Vs) {
    goo(1, std::forward<Ts>(vs)..., 42);
}




                      Quickoffice Proprietary and Confidential - Not for Disclosure   5
Expansion rules



Usage                           Expansion result
Ts...                           T1, … , Tn
Ts&...                          T1&, … , Tn&
A<Ts, B>::foo...                A<T1, B>::foo , … , A<Tn, B>::foo
A<const Ts&, Us>...             A<const T1&, U1>, … , A<constTn&, Un>
pow(vs,42)...                   pow(v1, 42), … , pow(vn, 42)




                      Quickoffice Proprietary and Confidential - Not for Disclosure   6
Where to use?

• Initializer lists
int a[] = { vs... };


• Base class specifier
template<typename... Ts>
struct A : B<Ts>...
{
};


• Class members initializer lists
template<typename... Us>
A(Us... vs) : B<Ts>(vs)... {}


                       Quickoffice Proprietary and Confidential - Not for Disclosure   7
Where to use?

• Template arguments lists
std::map<Ts...>foo;


• Exception specifications


• Capture lists
template<class... Ts>
voidfoo(Ts... vs) {
autolamda = [&vs...] { returngoo(vs...); }
lamda();
}



                      Quickoffice Proprietary and Confidential - Not for Disclosure   8
Multiple expansions


template<class... Ts>
voidfoo(Ts... vs)
{
goo(A<Ts...>::hoo(vs)...);
goo(A<Ts...>::hoo(vs...));
goo(A<Ts>::hoo(vs)...);
}




                    Quickoffice Proprietary and Confidential - Not for Disclosure   9
Where is used?


•   std::make_shared
template<class T, class... Ts>
shared_ptr<T>make_shared(Ts&&... vs);


•   std::vector::emplace_back
template<class... Args>
voidemplace_back(Args&&... args);




                   Quickoffice Proprietary and Confidential - Not for Disclosure   10
Typesafeprintf

• Stock printf:
  –   Fast
  –   Thread-safe
  –   Convenient
  –   Ubiquitously known
  –   Utterly unsafe
• Goal: add verification of the provided parameters




                  Quickoffice Proprietary and Confidential - Not for Disclosure   11
Typesafeprintf

• Adaptation routines
template<class T>
Typenameenable_if<is_integral<T>::value, long>::type
normalizeArg(Targ) { returnarg; }

template<class T>
typenameenable_if<is_floating_point<T>::value, double>::type
normalizeArg(Targ) { returnarg; }

template<class T>
typenameenable_if<is_pointer<T>::value, T>::type
normalizeArg(Targ) { returnarg; }

constchar* normalizeArg(const string&arg)
{ returnarg.c_str(); }

                         Quickoffice Proprietary and Confidential - Not for Disclosure   12
Typesafeprintf



// Not really safe yet
template<typename... Ts>
intsafe_printf(constchar* format, const Ts&... ts)
{
returnprintf(format, normalizeArg(ts)...);
}




                     Quickoffice Proprietary and Confidential - Not for Disclosure   13
Typesafeprintf

• Implement verification routine for argument-less call


voidcheck_printf(constchar * f)
{
for (; *f; ++f)
{
if (*f != ’%’ || *++f == ’%’) continue;
throwExc("Bad format");
    }
}




                      Quickoffice Proprietary and Confidential - Not for Disclosure   14
Typesafeprintf

template<class T, typename... Ts>
voidcheck_printf(constchar * f, const T&t, const Ts&... ts)
{
for (; *f; ++f)
    {
if (*f != ’%’ || *++f == ’%’) continue;
switch (*f)
       {
default: throwExc("Invalid format char: %", *f);
case ’f’: case ’g’:
ENFORCE(is_floating_point<T>::value);
break;
case ’s’: . . .
       }
returncheck_printf(++f, ts...); // AHA!!!
    }
throwExc("Too few format specifiers.");
}
                     Quickoffice Proprietary and Confidential - Not for Disclosure   15
Typesafeprintf

• Final step

template<typename... Ts>
intsafe_printf(constchar* format, const Ts&... ts)
{
check_printf(format, normalizeArg(ts)...);
returnprintf(format, normalizeArg(ts)...);
}




                    Quickoffice Proprietary and Confidential - Not for Disclosure   16
Clang
•   Motivation
•   Diagnostics
•   Static analysis
•   Dynamic analysis
•   Current state
•   Tool sample




                 Quickoffice Proprietary and Confidential - Not for Disclosure   17
Why?

• Performance
• Diagnostics
• Tools




                Quickoffice Proprietary and Confidential - Not for Disclosure   18
Why?

intw = 0;
for (inti = 0; i<3; i++)
w += w * 2;



$ gcc -fsyntax-only test.c
test.c:2: error: expected identifier or ‘(’ before ‘for’
test.c:2: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘<’ token
test.c:2: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘++’
   token




                       Quickoffice Proprietary and Confidential - Not for Disclosure   19
Why?

“... is there a reason for not making the
 [GCC] front ends dynamic libraries
which could be linked by any program
that wants to parse source code?”


                    “One of our main goals for GCC is to prevent
                   any parts of it from being used together with
                  non-free software. Thus, we have deliberately
                  avoided many things that might possibly have
                          the effect of facilitating such usage...”
                                               - Richard Stallman

                 Quickoffice Proprietary and Confidential - Not for Disclosure   20
Why?

#define FOO 0
intfoo() {
intx;
// ...
x = x + FOO;
// ...
returnx;
}

#define FOO 0
intfoo() {
intx;
// ...
x = x;
// ...
returnx;
}
                Quickoffice Proprietary and Confidential - Not for Disclosure   21
Diagnostics



template<int N>struct S1 { intarr[N - 5]; };
template<typename T>struct S2 { S1<sizeof(T)> s1; };
template<typename T>voidfoo(Tx) { S2<T> s2; }
void test() { foo(42); }




                   Quickoffice Proprietary and Confidential - Not for Disclosure   22
Diagnostics

$ clang++ -std=c++11 -fsyntax-only test.cpp
test.cpp:1:38:error:'arr' declared as an array with a negative size
template <int N>struct S1 { intarr[N - 5]; };
^~~~~
test.cpp:2:49: note: in instantiation of template class 'S1<4>' requested here
template <typename T>struct S2 { S1<sizeof(T)> s1; };
^
test.cpp:3:45: note: in instantiation of template class 'S2<int>' requested here
template <typename T> void foo(Tx) { S2<T> s2; }
^
test.cpp:4:15: note: in instantiation of function template specialization 'foo<int>'
    requested here
void test() { foo(42); }
^
1 error generated.




                         Quickoffice Proprietary and Confidential - Not for Disclosure   23
Diagnostics



#define M1(x, y, z) y();
#define M2(x, y, z) M1(x, y, z)
void test() {
   M2(a, b, c)
;}




                     Quickoffice Proprietary and Confidential - Not for Disclosure   24
Diagnostics

$ clang++ -std=c++11 -fsyntax-only test.cpp
test.cpp:4:11: error: use of undeclared identifier 'b’
   M2(a, b, c);
^
test.cpp:2:27: note: expanded from macro 'M2'
#define M2(x, y, z) M1(x, y, z)
^
test.cpp:1:21: note: expanded from macro 'M1'
#define M1(x, y, z) y();
^
1 error generated.

$ g++ -fsyntax-only test.cpp
test.cpp: In function ‘void test()’:
test.cpp:4: error: ‘b’ was not declared in this scope




                         Quickoffice Proprietary and Confidential - Not for Disclosure   25
Diagnostics



structBaseType {};
structDerivedType : publicBaseType {
staticintbase_type;
DerivedType() : basetype() {}
};




                  Quickoffice Proprietary and Confidential - Not for Disclosure   26
Diagnostics

% clang++ -std=c++11 -fsyntax-only typo1.cpp
typo1.cpp:4:19: error:initializer 'basetype' does not name a non-static
    data member or base class; did you mean the base class 'BaseType’?
DerivedType() : basetype() {}
^~~~~~~~
BaseType
typo1.cpp:2:22: note: base class 'BaseType' specified here
structDerivedType : public BaseType {
^~~~~~~~~~~~~~~

1 error generated.




                     Quickoffice Proprietary and Confidential - Not for Disclosure   27
Diagnostics



#include <sys/stat.h>
intfoo(intx, struct stat* P)
{
return P->st_blocksize * 2;
}




                    Quickoffice Proprietary and Confidential - Not for Disclosure   28
Diagnostics

$ clang++ -std=c++11 -fsyntax-only test.cpp
test.cpp:3:13:error:no member named 'st_blocksize' in 'stat'; did you
    mean 'st_blksize'?
  return P->st_blocksize*2;
         ^~~~~~~~~~~~
st_blksize
/usr/include/sys/stat.h:225:13: note: 'st_blksize' declared here
struct stat __DARWIN_STRUCT_STAT64;
         ^
/usr/include/sys/stat.h:212:12: note: expanded from macro
    '__DARWIN_STRUCT_STAT64'
blksize_tst_blksize; /*... */ 
^
1 error generated.




                   Quickoffice Proprietary and Confidential - Not for Disclosure   29
Diagnostics



template<class T, class U>struct S {};
template<typename... Ts>voidf(Ts...);

template<typename... Ts>struct X {
template<typename... Us>voidg() {
f(S<Ts, Us>()...);
   }
};

voidtest(X<int, float>x)
{
x.g<int, float, double>();
}



                     Quickoffice Proprietary and Confidential - Not for Disclosure   30
Diagnostics

$ clang++ -std=c++11 -fsyntax-only test.cpp
test.cpp:8:22: error: pack expansion contains parameter packs 'Ts' and
    'Us' that have different lengths (2 vs. 3)
f(S<Ts, Us>()...);
         ~~ ~~ ^
test.cpp:14:7: note: in instantiation of function template specialization 'X<int,
    float>::g<int, float, double>' requested here
x.g<int, float, double>();
     ^
1 error generated.




                      Quickoffice Proprietary and Confidential - Not for Disclosure   31
Diagnostics



#include <memory.h>
struct S { int a, b, c; float vec[16]; };
voidtest(S *s)
{
// ...
memset(s, 0, sizeof(s));
// ...
}




                      Quickoffice Proprietary and Confidential - Not for Disclosure   32
Diagnostics

$ clang++ -std=c++11 -fsyntax-only test.cpp
test.cpp:5:25: warning: argument to 'sizeof' in 'memset' call is the same
    expression as the destination; did you mean to dereference it? [-
    Wsizeof-pointer-memaccess]
memset(s, 0, sizeof(s));
       ~       ^
1 warning generated.




                    Quickoffice Proprietary and Confidential - Not for Disclosure   33
Diagnostics



intfoo() {
int arr[42];
// ...
return arr[42];
}




                  Quickoffice Proprietary and Confidential - Not for Disclosure   34
Diagnostics

$ clang++ -std=c++11 -fsyntax-only test.cpp
test.cpp:4:12: warning: array index of '42' indexes past the end of an array
    (that contains 42 elements) [-Warray-bounds]
   return arr[42];
        ^ ~~
test.cpp:2:5: note: array 'arr' declared here
int arr[42];
   ^
1 warning generated.




                    Quickoffice Proprietary and Confidential - Not for Disclosure   35
Diagnostics



staticconstlonglong
DiskCacheSize = 8<<30; // 8 Gigs




                   Quickoffice Proprietary and Confidential - Not for Disclosure   36
Diagnostics

$ clang++ -std=c++11 -fsyntax-only test.cpp
test.cpp:2:23: warning: signed shift result (0x200000000) requires 35 bits
    to represent, but 'int' only has 32 bits [-Wshift-overflow]
DiskCacheSize = 8 << 30; // 8 Gigs
             ~ ^ ~~
1 warning generated.




                   Quickoffice Proprietary and Confidential - Not for Disclosure   37
Diagnostics



voidtest(boolb, doublex, doubley)
{
if (b || x<y&&x>0)
    {
// ...
    }
}




                   Quickoffice Proprietary and Confidential - Not for Disclosure   38
Diagnostics

$ clang++ -std=c++11 -fsyntax-only test.cpp
test.cpp:2:19: warning: '&&' within '||' [-Wlogical-op-parentheses]
  if (b || x<y&&x> 0) {
        ~~ ~~~~~~^~~~~~~~
test.cpp:2:19: note: place parentheses around the '&&' expression to silence
     this warning
  if (b || x<y&&x> 0) {
              ^
          (       )
1 warning generated.




                    Quickoffice Proprietary and Confidential - Not for Disclosure   39
Diagnostics



constexprintarr_size = 42;
constexprint N = 44;
voidf(int);int test()
{
intarr[arr_size];
// ...
f(arr[N]);
// ...
if (N <arr_size) returnarr[N];
return0;
}




                     Quickoffice Proprietary and Confidential - Not for Disclosure   40
Diagnostics

$ clang++ -std=c++11 -fsyntax-only test.cpp
test.cpp:7:7: warning: array index of '44' indexes past the end of an array
    (that contains 42 elements) [-Warray-bounds]
f(arr[N]);
     ^ ~
test.cpp:5:5:note: array 'arr' declared here
intarr[arr_size];
   ^
1 warning generated.




                    Quickoffice Proprietary and Confidential - Not for Disclosure   41
Static Analysis

structmutex {
void lock();
void unlock();
};

mutexm;
intx;
boolfoo();
bool bar();
void test() {
m.lock();
while (foo()) {
m.unlock();
if (bar()) {
if (x<42&&foo()){
continue;
         }
      }
m.lock();
    }
}
                    Quickoffice Proprietary and Confidential - Not for Disclosure   42
Static Analysis

struct [[ts::lockable]] mutex {
void lock() [[ts::exclusive_lock_function]];
void unlock() [[ts::unlock_function]];
};

mutexm;
intx [[ts::guarded_by(m)]];
boolfoo() [[ts::exclusive_locks_required(m)]];
bool bar();
void test() {
m.lock();
while (foo()) {
m.unlock();
if (bar()) {
if (x<42&&foo()){
continue;
         }
      }
m.lock();
    }
}
                      Quickoffice Proprietary and Confidential - Not for Disclosure   43
Static Analysis

struct __attribute__((lockable)) mutex {
void lock() __attribute__((exclusive_lock_function));
void unlock() __attribute__((unlock_function));
};

mutexm;
intx__attribute__((guarded_by(m)));
boolfoo() __attribute__((exclusive_locks_required(m)));
bool bar();
void test() {
m.lock();
while (foo()) {
m.unlock();
if (bar()) {
if (x<42&&foo()){
continue;
         }
      }
m.lock();
    }
}
                      Quickoffice Proprietary and Confidential - Not for Disclosure   44
Diagnostics

$ clang++ -std=c++11 -fsyntax-only -Wthread-safety test.cpp
test.cpp:11:5: warning: expecting mutex 'm' to be locked at start of each
    loop [-Wthread-safety]
m.lock();
   ^
test.cpp:11:5: warning:mutex 'm' is still locked at the end of function [-
    Wthread-safety]
test.cpp:15:17: warning: reading variable 'x' requires locking 'm' [-
    Wthread-safety]
        if (x< 42 &&foo()) {
            ^
test.cpp:19:9: warning:mutex 'm' is still locked at the end of its scope [-
    Wthread-safety]
m.lock();
      ^
4 warnings generated.



                    Quickoffice Proprietary and Confidential - Not for Disclosure   45
Current Status

• Platforms:
  + Linux
  + Mac OS X
  – Windows
• C++11 features:
  + Almost all features implemented in v2.9+/SVN
  – Missing features:
      • Generalized attributes
      • Inheriting constructors
      • Concurrency




                    Quickoffice Proprietary and Confidential - Not for Disclosure   46
Brief architecture overview

• GCC compatible
• Library based architecture
  – libsupport, libsystem, libbasic, libast, liblex, libparse, libsema,
    libcodegen, librewrite, libanalysis, libindex
• One kind of as AST for C++/C and Objective-C
• Visitor interface ASTConsumer for Front-end actions




                    Quickoffice Proprietary and Confidential - Not for Disclosure   47
Sample ASTConsumer


classPrintFunctionsConsumer : publicASTConsumer
{
public:
virtualvoidHandleTopLevelDecl(DeclGroupRef DG)
    {
for (DeclGroupRef::iterator it = DG.begin();
         it != DG.end();
         ++it)
      {
constDecl* D = *it;
if (constNamedDecl* ND = dyn_cast<NamedDecl>(D))
llvm::errs() << ” topleveldecl : ” ”
<< ND->getNameAsString()
<< ” ” n ”;
      }
    }
};


                   Quickoffice Proprietary and Confidential - Not for Disclosure   48
Thirdparty tools

http://code.google.com/p/include-what-you-use/

"Include what you use" means this: for every symbol (type,
function variable, or macro) that you use in foo.cc, either foo.cc
or foo.h should #include a .h file that exports the declaration of
that symbol. The include-what-you-use tool is a program that
can be built with the clang libraries in order to analyze
#includes of source files to find include-what-you-use
violations, and suggest fixes for them.




                 Quickoffice Proprietary and Confidential - Not for Disclosure   49

More Related Content

What's hot

Data Structure Project File
Data Structure Project FileData Structure Project File
Data Structure Project FileDeyvessh kumar
 
[C++ Korea] Effective Modern C++ Study, Item 11 - 13
[C++ Korea] Effective Modern C++ Study, Item 11 - 13[C++ Korea] Effective Modern C++ Study, Item 11 - 13
[C++ Korea] Effective Modern C++ Study, Item 11 - 13Chris Ohk
 
李建忠、侯捷设计模式讲义
李建忠、侯捷设计模式讲义李建忠、侯捷设计模式讲义
李建忠、侯捷设计模式讲义yiditushe
 
Handling Exceptions In C &amp; C++ [Part B] Ver 2
Handling Exceptions In C &amp; C++ [Part B] Ver 2Handling Exceptions In C &amp; C++ [Part B] Ver 2
Handling Exceptions In C &amp; C++ [Part B] Ver 2ppd1961
 
Coding Guidelines - Crafting Clean Code
Coding Guidelines - Crafting Clean CodeCoding Guidelines - Crafting Clean Code
Coding Guidelines - Crafting Clean CodeGanesh Samarthyam
 
TDD in C - Recently Used List Kata
TDD in C - Recently Used List KataTDD in C - Recently Used List Kata
TDD in C - Recently Used List KataOlve Maudal
 
Data structure new lab manual
Data structure  new lab manualData structure  new lab manual
Data structure new lab manualSANTOSH RATH
 
12. Java Exceptions and error handling
12. Java Exceptions and error handling12. Java Exceptions and error handling
12. Java Exceptions and error handlingIntro C# Book
 
Best Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' MistakesBest Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' MistakesAndrey Karpov
 
SoCal Code Camp 2015: An introduction to Java 8
SoCal Code Camp 2015: An introduction to Java 8SoCal Code Camp 2015: An introduction to Java 8
SoCal Code Camp 2015: An introduction to Java 8Chaitanya Ganoo
 
Writing beautiful code with Java 8
Writing beautiful code with Java 8Writing beautiful code with Java 8
Writing beautiful code with Java 8Sergiu Mircea Indrie
 
Simulado java se 7 programmer
Simulado java se 7 programmerSimulado java se 7 programmer
Simulado java se 7 programmerMiguel Vilaca
 
C++11 smart pointer
C++11 smart pointerC++11 smart pointer
C++11 smart pointerLei Yu
 
Applying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedApplying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedPascal-Louis Perez
 
Algoritmos sujei
Algoritmos sujeiAlgoritmos sujei
Algoritmos sujeigersonjack
 

What's hot (20)

Templates
TemplatesTemplates
Templates
 
Data Structure Project File
Data Structure Project FileData Structure Project File
Data Structure Project File
 
[C++ Korea] Effective Modern C++ Study, Item 11 - 13
[C++ Korea] Effective Modern C++ Study, Item 11 - 13[C++ Korea] Effective Modern C++ Study, Item 11 - 13
[C++ Korea] Effective Modern C++ Study, Item 11 - 13
 
Data struture lab
Data struture labData struture lab
Data struture lab
 
李建忠、侯捷设计模式讲义
李建忠、侯捷设计模式讲义李建忠、侯捷设计模式讲义
李建忠、侯捷设计模式讲义
 
Handling Exceptions In C &amp; C++ [Part B] Ver 2
Handling Exceptions In C &amp; C++ [Part B] Ver 2Handling Exceptions In C &amp; C++ [Part B] Ver 2
Handling Exceptions In C &amp; C++ [Part B] Ver 2
 
Coding Guidelines - Crafting Clean Code
Coding Guidelines - Crafting Clean CodeCoding Guidelines - Crafting Clean Code
Coding Guidelines - Crafting Clean Code
 
TDD in C - Recently Used List Kata
TDD in C - Recently Used List KataTDD in C - Recently Used List Kata
TDD in C - Recently Used List Kata
 
Data structure new lab manual
Data structure  new lab manualData structure  new lab manual
Data structure new lab manual
 
12. Java Exceptions and error handling
12. Java Exceptions and error handling12. Java Exceptions and error handling
12. Java Exceptions and error handling
 
Best Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' MistakesBest Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' Mistakes
 
7
77
7
 
SoCal Code Camp 2015: An introduction to Java 8
SoCal Code Camp 2015: An introduction to Java 8SoCal Code Camp 2015: An introduction to Java 8
SoCal Code Camp 2015: An introduction to Java 8
 
Introduzione al TDD
Introduzione al TDDIntroduzione al TDD
Introduzione al TDD
 
Writing beautiful code with Java 8
Writing beautiful code with Java 8Writing beautiful code with Java 8
Writing beautiful code with Java 8
 
Simulado java se 7 programmer
Simulado java se 7 programmerSimulado java se 7 programmer
Simulado java se 7 programmer
 
7 functions
7  functions7  functions
7 functions
 
C++11 smart pointer
C++11 smart pointerC++11 smart pointer
C++11 smart pointer
 
Applying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing SpeedApplying Compiler Techniques to Iterate At Blazing Speed
Applying Compiler Techniques to Iterate At Blazing Speed
 
Algoritmos sujei
Algoritmos sujeiAlgoritmos sujei
Algoritmos sujei
 

Viewers also liked (20)

Brain
BrainBrain
Brain
 
114
114114
114
 
Diapositiva 1
Diapositiva 1Diapositiva 1
Diapositiva 1
 
Unit 1b
Unit 1bUnit 1b
Unit 1b
 
Getting Started
Getting StartedGetting Started
Getting Started
 
Quickword How To
Quickword How ToQuickword How To
Quickword How To
 
evernote Quickword How To
evernote Quickword How Toevernote Quickword How To
evernote Quickword How To
 
New_PPTX_FileSavedOnEvernote_19
New_PPTX_FileSavedOnEvernote_19New_PPTX_FileSavedOnEvernote_19
New_PPTX_FileSavedOnEvernote_19
 
File Manager How To
File Manager How ToFile Manager How To
File Manager How To
 
Quickword How To
Quickword How ToQuickword How To
Quickword How To
 
Quickword How To
Quickword How ToQuickword How To
Quickword How To
 
mac_pp_2011
mac_pp_2011mac_pp_2011
mac_pp_2011
 
what you cannot recover
what you cannot recoverwhat you cannot recover
what you cannot recover
 
PPTX_FileSavedAsOnGoogleDocs_31
PPTX_FileSavedAsOnGoogleDocs_31PPTX_FileSavedAsOnGoogleDocs_31
PPTX_FileSavedAsOnGoogleDocs_31
 
mac_pp_2011
mac_pp_2011mac_pp_2011
mac_pp_2011
 
lectures
lectureslectures
lectures
 
QAducation Cursusinformatie2012v2
QAducation Cursusinformatie2012v2QAducation Cursusinformatie2012v2
QAducation Cursusinformatie2012v2
 
Long lists
Long listsLong lists
Long lists
 
1
11
1
 
A
AA
A
 

Similar to report

Debugging and Profiling C++ Template Metaprograms
Debugging and Profiling C++ Template MetaprogramsDebugging and Profiling C++ Template Metaprograms
Debugging and Profiling C++ Template MetaprogramsPlatonov Sergey
 
App secforum2014 andrivet-cplusplus11-metaprogramming_applied_to_software_obf...
App secforum2014 andrivet-cplusplus11-metaprogramming_applied_to_software_obf...App secforum2014 andrivet-cplusplus11-metaprogramming_applied_to_software_obf...
App secforum2014 andrivet-cplusplus11-metaprogramming_applied_to_software_obf...Cyber Security Alliance
 
Fundamentals of computer programming by Dr. A. Charan Kumari
Fundamentals of computer programming by Dr. A. Charan KumariFundamentals of computer programming by Dr. A. Charan Kumari
Fundamentals of computer programming by Dr. A. Charan KumariTHE NORTHCAP UNIVERSITY
 
The operation principles of PVS-Studio static code analyzer
The operation principles of PVS-Studio static code analyzerThe operation principles of PVS-Studio static code analyzer
The operation principles of PVS-Studio static code analyzerAndrey Karpov
 
Static code analysis: what? how? why?
Static code analysis: what? how? why?Static code analysis: what? how? why?
Static code analysis: what? how? why?Andrey Karpov
 
Découvrir dtrace en ligne de commande.
Découvrir dtrace en ligne de commande.Découvrir dtrace en ligne de commande.
Découvrir dtrace en ligne de commande.CocoaHeads France
 
TEMPLATES IN JAVA
TEMPLATES IN JAVATEMPLATES IN JAVA
TEMPLATES IN JAVAMuskanSony
 
Getting Started Cpp
Getting Started CppGetting Started Cpp
Getting Started CppLong Cao
 
Paradigmas de Linguagens de Programacao - Aula #5
Paradigmas de Linguagens de Programacao - Aula #5Paradigmas de Linguagens de Programacao - Aula #5
Paradigmas de Linguagens de Programacao - Aula #5Ismar Silveira
 
Headache from using mathematical software
Headache from using mathematical softwareHeadache from using mathematical software
Headache from using mathematical softwarePVS-Studio
 
Picking Mushrooms after Cppcheck
Picking Mushrooms after CppcheckPicking Mushrooms after Cppcheck
Picking Mushrooms after CppcheckAndrey Karpov
 
Milot Shala - C++ (OSCAL2014)
Milot Shala - C++ (OSCAL2014)Milot Shala - C++ (OSCAL2014)
Milot Shala - C++ (OSCAL2014)Open Labs Albania
 
Cluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in CCluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in CSteffen Wenz
 

Similar to report (20)

Debugging and Profiling C++ Template Metaprograms
Debugging and Profiling C++ Template MetaprogramsDebugging and Profiling C++ Template Metaprograms
Debugging and Profiling C++ Template Metaprograms
 
App secforum2014 andrivet-cplusplus11-metaprogramming_applied_to_software_obf...
App secforum2014 andrivet-cplusplus11-metaprogramming_applied_to_software_obf...App secforum2014 andrivet-cplusplus11-metaprogramming_applied_to_software_obf...
App secforum2014 andrivet-cplusplus11-metaprogramming_applied_to_software_obf...
 
Fundamentals of computer programming by Dr. A. Charan Kumari
Fundamentals of computer programming by Dr. A. Charan KumariFundamentals of computer programming by Dr. A. Charan Kumari
Fundamentals of computer programming by Dr. A. Charan Kumari
 
The operation principles of PVS-Studio static code analyzer
The operation principles of PVS-Studio static code analyzerThe operation principles of PVS-Studio static code analyzer
The operation principles of PVS-Studio static code analyzer
 
Static code analysis: what? how? why?
Static code analysis: what? how? why?Static code analysis: what? how? why?
Static code analysis: what? how? why?
 
Découvrir dtrace en ligne de commande.
Découvrir dtrace en ligne de commande.Découvrir dtrace en ligne de commande.
Découvrir dtrace en ligne de commande.
 
C++ idioms.pptx
C++ idioms.pptxC++ idioms.pptx
C++ idioms.pptx
 
Summary of C++17 features
Summary of C++17 featuresSummary of C++17 features
Summary of C++17 features
 
TEMPLATES IN JAVA
TEMPLATES IN JAVATEMPLATES IN JAVA
TEMPLATES IN JAVA
 
Getting Started Cpp
Getting Started CppGetting Started Cpp
Getting Started Cpp
 
Lec-1c.pdf
Lec-1c.pdfLec-1c.pdf
Lec-1c.pdf
 
Paradigmas de Linguagens de Programacao - Aula #5
Paradigmas de Linguagens de Programacao - Aula #5Paradigmas de Linguagens de Programacao - Aula #5
Paradigmas de Linguagens de Programacao - Aula #5
 
C Programming Homework Help
C Programming Homework HelpC Programming Homework Help
C Programming Homework Help
 
02basics
02basics02basics
02basics
 
Headache from using mathematical software
Headache from using mathematical softwareHeadache from using mathematical software
Headache from using mathematical software
 
Picking Mushrooms after Cppcheck
Picking Mushrooms after CppcheckPicking Mushrooms after Cppcheck
Picking Mushrooms after Cppcheck
 
Golang dot-testing-lite
Golang dot-testing-liteGolang dot-testing-lite
Golang dot-testing-lite
 
Oops lecture 1
Oops lecture 1Oops lecture 1
Oops lecture 1
 
Milot Shala - C++ (OSCAL2014)
Milot Shala - C++ (OSCAL2014)Milot Shala - C++ (OSCAL2014)
Milot Shala - C++ (OSCAL2014)
 
Cluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in CCluj.py Meetup: Extending Python in C
Cluj.py Meetup: Extending Python in C
 

More from Quickoffice Test (20)

call02
call02call02
call02
 
call03
call03call03
call03
 
call06
call06call06
call06
 
call07
call07call07
call07
 
test
testtest
test
 
EGNYTE
EGNYTEEGNYTE
EGNYTE
 
egnyte rename
egnyte renameegnyte rename
egnyte rename
 
Quickword How To
Quickword How ToQuickword How To
Quickword How To
 
evi
evievi
evi
 
Docx test
Docx testDocx test
Docx test
 
Presentation
PresentationPresentation
Presentation
 
april
aprilapril
april
 
April
AprilApril
April
 
April
AprilApril
April
 
April
AprilApril
April
 
test
testtest
test
 
!!!zzz To
!!!zzz To!!!zzz To
!!!zzz To
 
!!!zzz itttest1
!!!zzz itttest1!!!zzz itttest1
!!!zzz itttest1
 
Ciao_questa_è_una_prova_da_Quickoffice
Ciao_questa_è_una_prova_da_QuickofficeCiao_questa_è_una_prova_da_Quickoffice
Ciao_questa_è_una_prova_da_Quickoffice
 
1 georgia
1  georgia1  georgia
1 georgia
 

report

  • 1. Going Native Highlights Introduction to Variadic Templates. Clang overview.
  • 2. Variadic Templates • Fundamentals • Usage • Samples Quickoffice Proprietary and Confidential - Not for Disclosure 2
  • 3. Fundamentals Class declaration: template<typename... Ts> class A { }; Function declaration: template<typename... Ts> voidfoo(const Ts&... vs) { } Quickoffice Proprietary and Confidential - Not for Disclosure 3
  • 4. What is Ts and vs? • Ts is an alias for a list of types • vs is an alias for a list of values typedef Ts MyList; // error! Ts var;// error! auto copy = vs;// error! Quickoffice Proprietary and Confidential - Not for Disclosure 4
  • 5. Parameters Packs Usage • Get pack size size_t items = sizeof...(Ts); // or vs • Expand back template<typename... Ts> voidfoo(const Ts&... Vs) { goo(1, std::forward<Ts>(vs)..., 42); } Quickoffice Proprietary and Confidential - Not for Disclosure 5
  • 6. Expansion rules Usage Expansion result Ts... T1, … , Tn Ts&... T1&, … , Tn& A<Ts, B>::foo... A<T1, B>::foo , … , A<Tn, B>::foo A<const Ts&, Us>... A<const T1&, U1>, … , A<constTn&, Un> pow(vs,42)... pow(v1, 42), … , pow(vn, 42) Quickoffice Proprietary and Confidential - Not for Disclosure 6
  • 7. Where to use? • Initializer lists int a[] = { vs... }; • Base class specifier template<typename... Ts> struct A : B<Ts>... { }; • Class members initializer lists template<typename... Us> A(Us... vs) : B<Ts>(vs)... {} Quickoffice Proprietary and Confidential - Not for Disclosure 7
  • 8. Where to use? • Template arguments lists std::map<Ts...>foo; • Exception specifications • Capture lists template<class... Ts> voidfoo(Ts... vs) { autolamda = [&vs...] { returngoo(vs...); } lamda(); } Quickoffice Proprietary and Confidential - Not for Disclosure 8
  • 9. Multiple expansions template<class... Ts> voidfoo(Ts... vs) { goo(A<Ts...>::hoo(vs)...); goo(A<Ts...>::hoo(vs...)); goo(A<Ts>::hoo(vs)...); } Quickoffice Proprietary and Confidential - Not for Disclosure 9
  • 10. Where is used? • std::make_shared template<class T, class... Ts> shared_ptr<T>make_shared(Ts&&... vs); • std::vector::emplace_back template<class... Args> voidemplace_back(Args&&... args); Quickoffice Proprietary and Confidential - Not for Disclosure 10
  • 11. Typesafeprintf • Stock printf: – Fast – Thread-safe – Convenient – Ubiquitously known – Utterly unsafe • Goal: add verification of the provided parameters Quickoffice Proprietary and Confidential - Not for Disclosure 11
  • 12. Typesafeprintf • Adaptation routines template<class T> Typenameenable_if<is_integral<T>::value, long>::type normalizeArg(Targ) { returnarg; } template<class T> typenameenable_if<is_floating_point<T>::value, double>::type normalizeArg(Targ) { returnarg; } template<class T> typenameenable_if<is_pointer<T>::value, T>::type normalizeArg(Targ) { returnarg; } constchar* normalizeArg(const string&arg) { returnarg.c_str(); } Quickoffice Proprietary and Confidential - Not for Disclosure 12
  • 13. Typesafeprintf // Not really safe yet template<typename... Ts> intsafe_printf(constchar* format, const Ts&... ts) { returnprintf(format, normalizeArg(ts)...); } Quickoffice Proprietary and Confidential - Not for Disclosure 13
  • 14. Typesafeprintf • Implement verification routine for argument-less call voidcheck_printf(constchar * f) { for (; *f; ++f) { if (*f != ’%’ || *++f == ’%’) continue; throwExc("Bad format"); } } Quickoffice Proprietary and Confidential - Not for Disclosure 14
  • 15. Typesafeprintf template<class T, typename... Ts> voidcheck_printf(constchar * f, const T&t, const Ts&... ts) { for (; *f; ++f) { if (*f != ’%’ || *++f == ’%’) continue; switch (*f) { default: throwExc("Invalid format char: %", *f); case ’f’: case ’g’: ENFORCE(is_floating_point<T>::value); break; case ’s’: . . . } returncheck_printf(++f, ts...); // AHA!!! } throwExc("Too few format specifiers."); } Quickoffice Proprietary and Confidential - Not for Disclosure 15
  • 16. Typesafeprintf • Final step template<typename... Ts> intsafe_printf(constchar* format, const Ts&... ts) { check_printf(format, normalizeArg(ts)...); returnprintf(format, normalizeArg(ts)...); } Quickoffice Proprietary and Confidential - Not for Disclosure 16
  • 17. Clang • Motivation • Diagnostics • Static analysis • Dynamic analysis • Current state • Tool sample Quickoffice Proprietary and Confidential - Not for Disclosure 17
  • 18. Why? • Performance • Diagnostics • Tools Quickoffice Proprietary and Confidential - Not for Disclosure 18
  • 19. Why? intw = 0; for (inti = 0; i<3; i++) w += w * 2; $ gcc -fsyntax-only test.c test.c:2: error: expected identifier or ‘(’ before ‘for’ test.c:2: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘<’ token test.c:2: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘++’ token Quickoffice Proprietary and Confidential - Not for Disclosure 19
  • 20. Why? “... is there a reason for not making the [GCC] front ends dynamic libraries which could be linked by any program that wants to parse source code?” “One of our main goals for GCC is to prevent any parts of it from being used together with non-free software. Thus, we have deliberately avoided many things that might possibly have the effect of facilitating such usage...” - Richard Stallman Quickoffice Proprietary and Confidential - Not for Disclosure 20
  • 21. Why? #define FOO 0 intfoo() { intx; // ... x = x + FOO; // ... returnx; } #define FOO 0 intfoo() { intx; // ... x = x; // ... returnx; } Quickoffice Proprietary and Confidential - Not for Disclosure 21
  • 22. Diagnostics template<int N>struct S1 { intarr[N - 5]; }; template<typename T>struct S2 { S1<sizeof(T)> s1; }; template<typename T>voidfoo(Tx) { S2<T> s2; } void test() { foo(42); } Quickoffice Proprietary and Confidential - Not for Disclosure 22
  • 23. Diagnostics $ clang++ -std=c++11 -fsyntax-only test.cpp test.cpp:1:38:error:'arr' declared as an array with a negative size template <int N>struct S1 { intarr[N - 5]; }; ^~~~~ test.cpp:2:49: note: in instantiation of template class 'S1<4>' requested here template <typename T>struct S2 { S1<sizeof(T)> s1; }; ^ test.cpp:3:45: note: in instantiation of template class 'S2<int>' requested here template <typename T> void foo(Tx) { S2<T> s2; } ^ test.cpp:4:15: note: in instantiation of function template specialization 'foo<int>' requested here void test() { foo(42); } ^ 1 error generated. Quickoffice Proprietary and Confidential - Not for Disclosure 23
  • 24. Diagnostics #define M1(x, y, z) y(); #define M2(x, y, z) M1(x, y, z) void test() { M2(a, b, c) ;} Quickoffice Proprietary and Confidential - Not for Disclosure 24
  • 25. Diagnostics $ clang++ -std=c++11 -fsyntax-only test.cpp test.cpp:4:11: error: use of undeclared identifier 'b’ M2(a, b, c); ^ test.cpp:2:27: note: expanded from macro 'M2' #define M2(x, y, z) M1(x, y, z) ^ test.cpp:1:21: note: expanded from macro 'M1' #define M1(x, y, z) y(); ^ 1 error generated. $ g++ -fsyntax-only test.cpp test.cpp: In function ‘void test()’: test.cpp:4: error: ‘b’ was not declared in this scope Quickoffice Proprietary and Confidential - Not for Disclosure 25
  • 26. Diagnostics structBaseType {}; structDerivedType : publicBaseType { staticintbase_type; DerivedType() : basetype() {} }; Quickoffice Proprietary and Confidential - Not for Disclosure 26
  • 27. Diagnostics % clang++ -std=c++11 -fsyntax-only typo1.cpp typo1.cpp:4:19: error:initializer 'basetype' does not name a non-static data member or base class; did you mean the base class 'BaseType’? DerivedType() : basetype() {} ^~~~~~~~ BaseType typo1.cpp:2:22: note: base class 'BaseType' specified here structDerivedType : public BaseType { ^~~~~~~~~~~~~~~ 1 error generated. Quickoffice Proprietary and Confidential - Not for Disclosure 27
  • 28. Diagnostics #include <sys/stat.h> intfoo(intx, struct stat* P) { return P->st_blocksize * 2; } Quickoffice Proprietary and Confidential - Not for Disclosure 28
  • 29. Diagnostics $ clang++ -std=c++11 -fsyntax-only test.cpp test.cpp:3:13:error:no member named 'st_blocksize' in 'stat'; did you mean 'st_blksize'? return P->st_blocksize*2; ^~~~~~~~~~~~ st_blksize /usr/include/sys/stat.h:225:13: note: 'st_blksize' declared here struct stat __DARWIN_STRUCT_STAT64; ^ /usr/include/sys/stat.h:212:12: note: expanded from macro '__DARWIN_STRUCT_STAT64' blksize_tst_blksize; /*... */ ^ 1 error generated. Quickoffice Proprietary and Confidential - Not for Disclosure 29
  • 30. Diagnostics template<class T, class U>struct S {}; template<typename... Ts>voidf(Ts...); template<typename... Ts>struct X { template<typename... Us>voidg() { f(S<Ts, Us>()...); } }; voidtest(X<int, float>x) { x.g<int, float, double>(); } Quickoffice Proprietary and Confidential - Not for Disclosure 30
  • 31. Diagnostics $ clang++ -std=c++11 -fsyntax-only test.cpp test.cpp:8:22: error: pack expansion contains parameter packs 'Ts' and 'Us' that have different lengths (2 vs. 3) f(S<Ts, Us>()...); ~~ ~~ ^ test.cpp:14:7: note: in instantiation of function template specialization 'X<int, float>::g<int, float, double>' requested here x.g<int, float, double>(); ^ 1 error generated. Quickoffice Proprietary and Confidential - Not for Disclosure 31
  • 32. Diagnostics #include <memory.h> struct S { int a, b, c; float vec[16]; }; voidtest(S *s) { // ... memset(s, 0, sizeof(s)); // ... } Quickoffice Proprietary and Confidential - Not for Disclosure 32
  • 33. Diagnostics $ clang++ -std=c++11 -fsyntax-only test.cpp test.cpp:5:25: warning: argument to 'sizeof' in 'memset' call is the same expression as the destination; did you mean to dereference it? [- Wsizeof-pointer-memaccess] memset(s, 0, sizeof(s)); ~ ^ 1 warning generated. Quickoffice Proprietary and Confidential - Not for Disclosure 33
  • 34. Diagnostics intfoo() { int arr[42]; // ... return arr[42]; } Quickoffice Proprietary and Confidential - Not for Disclosure 34
  • 35. Diagnostics $ clang++ -std=c++11 -fsyntax-only test.cpp test.cpp:4:12: warning: array index of '42' indexes past the end of an array (that contains 42 elements) [-Warray-bounds] return arr[42]; ^ ~~ test.cpp:2:5: note: array 'arr' declared here int arr[42]; ^ 1 warning generated. Quickoffice Proprietary and Confidential - Not for Disclosure 35
  • 36. Diagnostics staticconstlonglong DiskCacheSize = 8<<30; // 8 Gigs Quickoffice Proprietary and Confidential - Not for Disclosure 36
  • 37. Diagnostics $ clang++ -std=c++11 -fsyntax-only test.cpp test.cpp:2:23: warning: signed shift result (0x200000000) requires 35 bits to represent, but 'int' only has 32 bits [-Wshift-overflow] DiskCacheSize = 8 << 30; // 8 Gigs ~ ^ ~~ 1 warning generated. Quickoffice Proprietary and Confidential - Not for Disclosure 37
  • 38. Diagnostics voidtest(boolb, doublex, doubley) { if (b || x<y&&x>0) { // ... } } Quickoffice Proprietary and Confidential - Not for Disclosure 38
  • 39. Diagnostics $ clang++ -std=c++11 -fsyntax-only test.cpp test.cpp:2:19: warning: '&&' within '||' [-Wlogical-op-parentheses] if (b || x<y&&x> 0) { ~~ ~~~~~~^~~~~~~~ test.cpp:2:19: note: place parentheses around the '&&' expression to silence this warning if (b || x<y&&x> 0) { ^ ( ) 1 warning generated. Quickoffice Proprietary and Confidential - Not for Disclosure 39
  • 40. Diagnostics constexprintarr_size = 42; constexprint N = 44; voidf(int);int test() { intarr[arr_size]; // ... f(arr[N]); // ... if (N <arr_size) returnarr[N]; return0; } Quickoffice Proprietary and Confidential - Not for Disclosure 40
  • 41. Diagnostics $ clang++ -std=c++11 -fsyntax-only test.cpp test.cpp:7:7: warning: array index of '44' indexes past the end of an array (that contains 42 elements) [-Warray-bounds] f(arr[N]); ^ ~ test.cpp:5:5:note: array 'arr' declared here intarr[arr_size]; ^ 1 warning generated. Quickoffice Proprietary and Confidential - Not for Disclosure 41
  • 42. Static Analysis structmutex { void lock(); void unlock(); }; mutexm; intx; boolfoo(); bool bar(); void test() { m.lock(); while (foo()) { m.unlock(); if (bar()) { if (x<42&&foo()){ continue; } } m.lock(); } } Quickoffice Proprietary and Confidential - Not for Disclosure 42
  • 43. Static Analysis struct [[ts::lockable]] mutex { void lock() [[ts::exclusive_lock_function]]; void unlock() [[ts::unlock_function]]; }; mutexm; intx [[ts::guarded_by(m)]]; boolfoo() [[ts::exclusive_locks_required(m)]]; bool bar(); void test() { m.lock(); while (foo()) { m.unlock(); if (bar()) { if (x<42&&foo()){ continue; } } m.lock(); } } Quickoffice Proprietary and Confidential - Not for Disclosure 43
  • 44. Static Analysis struct __attribute__((lockable)) mutex { void lock() __attribute__((exclusive_lock_function)); void unlock() __attribute__((unlock_function)); }; mutexm; intx__attribute__((guarded_by(m))); boolfoo() __attribute__((exclusive_locks_required(m))); bool bar(); void test() { m.lock(); while (foo()) { m.unlock(); if (bar()) { if (x<42&&foo()){ continue; } } m.lock(); } } Quickoffice Proprietary and Confidential - Not for Disclosure 44
  • 45. Diagnostics $ clang++ -std=c++11 -fsyntax-only -Wthread-safety test.cpp test.cpp:11:5: warning: expecting mutex 'm' to be locked at start of each loop [-Wthread-safety] m.lock(); ^ test.cpp:11:5: warning:mutex 'm' is still locked at the end of function [- Wthread-safety] test.cpp:15:17: warning: reading variable 'x' requires locking 'm' [- Wthread-safety] if (x< 42 &&foo()) { ^ test.cpp:19:9: warning:mutex 'm' is still locked at the end of its scope [- Wthread-safety] m.lock(); ^ 4 warnings generated. Quickoffice Proprietary and Confidential - Not for Disclosure 45
  • 46. Current Status • Platforms: + Linux + Mac OS X – Windows • C++11 features: + Almost all features implemented in v2.9+/SVN – Missing features: • Generalized attributes • Inheriting constructors • Concurrency Quickoffice Proprietary and Confidential - Not for Disclosure 46
  • 47. Brief architecture overview • GCC compatible • Library based architecture – libsupport, libsystem, libbasic, libast, liblex, libparse, libsema, libcodegen, librewrite, libanalysis, libindex • One kind of as AST for C++/C and Objective-C • Visitor interface ASTConsumer for Front-end actions Quickoffice Proprietary and Confidential - Not for Disclosure 47
  • 48. Sample ASTConsumer classPrintFunctionsConsumer : publicASTConsumer { public: virtualvoidHandleTopLevelDecl(DeclGroupRef DG) { for (DeclGroupRef::iterator it = DG.begin(); it != DG.end(); ++it) { constDecl* D = *it; if (constNamedDecl* ND = dyn_cast<NamedDecl>(D)) llvm::errs() << ” topleveldecl : ” ” << ND->getNameAsString() << ” ” n ”; } } }; Quickoffice Proprietary and Confidential - Not for Disclosure 48
  • 49. Thirdparty tools http://code.google.com/p/include-what-you-use/ "Include what you use" means this: for every symbol (type, function variable, or macro) that you use in foo.cc, either foo.cc or foo.h should #include a .h file that exports the declaration of that symbol. The include-what-you-use tool is a program that can be built with the clang libraries in order to analyze #includes of source files to find include-what-you-use violations, and suggest fixes for them. Quickoffice Proprietary and Confidential - Not for Disclosure 49