Add -Wextra-semi -Wundefined-func-template to the default CXXFLAGS

And fix the resulting compilation errors.

Change-Id: I2f8a8406542d297bfeeb4c922812ff1879a4dff6
Refs: #4248
diff --git a/.waf-tools/default-compiler-flags.py b/.waf-tools/default-compiler-flags.py
index 28340ed..3899b06 100644
--- a/.waf-tools/default-compiler-flags.py
+++ b/.waf-tools/default-compiler-flags.py
@@ -7,23 +7,34 @@
                    help='''Compile in debugging mode with minimal optimizations (-O0 or -Og)''')
 
 def configure(conf):
-    cxx = conf.env['CXX_NAME'] # CXX_NAME represents generic name of the compiler
+    conf.start_msg('Checking C++ compiler version')
+
+    cxx = conf.env['CXX_NAME'] # CXX_NAME is the generic name of the compiler
     ccver = tuple(int(i) for i in conf.env['CC_VERSION'])
+    errmsg = ''
+    warnmsg = ''
     if cxx == 'gcc':
         if ccver < (4, 8, 2):
-            conf.fatal('The version of gcc you are using (%s) is too old.\n'
-                       'The minimum supported gcc version is 4.8.2.' %
-                       '.'.join(conf.env['CC_VERSION']))
+            errmsg = ('The version of gcc you are using is too old.\n'
+                      'The minimum supported gcc version is 4.8.2.')
         flags = GccFlags()
     elif cxx == 'clang':
         if ccver < (3, 4, 0):
-            conf.fatal('The version of clang you are using (%s) is too old.\n'
-                       'The minimum supported clang version is 3.4.0.' %
-                       '.'.join(conf.env['CC_VERSION']))
+            errmsg = ('The version of clang you are using is too old.\n'
+                      'The minimum supported clang version is 3.4.0.')
         flags = ClangFlags()
     else:
+        warnmsg = 'Note: %s compiler is unsupported' % cxx
         flags = CompilerFlags()
-        Logs.warn('The code has not yet been tested with %s compiler' % cxx)
+
+    if errmsg:
+        conf.end_msg('.'.join(conf.env['CC_VERSION']), color='RED')
+        conf.fatal(errmsg)
+    elif warnmsg:
+        conf.end_msg('.'.join(conf.env['CC_VERSION']), color='YELLOW')
+        Logs.warn(warnmsg)
+    else:
+        conf.end_msg('.'.join(conf.env['CC_VERSION']))
 
     areCustomCxxflagsPresent = (len(conf.env.CXXFLAGS) > 0)
 
@@ -121,9 +132,9 @@
                               '-Wall',
                               '-Wextra',
                               '-Werror',
-                              '-Wno-unused-parameter',
-                              '-Wno-error=maybe-uninitialized', # Bug #1615
                               '-Wno-error=deprecated-declarations', # Bug #3795
+                              '-Wno-error=maybe-uninitialized', # Bug #1615
+                              '-Wno-unused-parameter',
                               ]
         flags['LINKFLAGS'] += ['-fuse-ld=gold', '-Wl,-O1']
         return flags
@@ -168,17 +179,27 @@
     def getDebugFlags(self, conf):
         flags = super(ClangFlags, self).getDebugFlags(conf)
         flags['CXXFLAGS'] += ['-fcolor-diagnostics',
-                              '-Wno-unused-local-typedef', # Bugs #2657 and #3209
-                              '-Wno-error=unneeded-internal-declaration', # Bug #1588
+                              '-Wextra-semi',
+                              '-Wundefined-func-template',
                               '-Wno-error=deprecated-register',
-                              '-Wno-error=keyword-macro', # Bug #3235
                               '-Wno-error=infinite-recursion', # Bug #3358
+                              '-Wno-error=keyword-macro', # Bug #3235
+                              '-Wno-error=unneeded-internal-declaration', # Bug #1588
+                              '-Wno-unused-local-typedef', # Bugs #2657 and #3209
                               ]
+        version = tuple(int(i) for i in conf.env['CC_VERSION'])
+        if version < (3, 9, 0) or (Utils.unversioned_sys_platform() == 'darwin' and version < (9, 0, 0)):
+            flags['CXXFLAGS'] += ['-Wno-unknown-pragmas']
         return flags
 
     def getOptimizedFlags(self, conf):
         flags = super(ClangFlags, self).getOptimizedFlags(conf)
         flags['CXXFLAGS'] += ['-fcolor-diagnostics',
+                              '-Wextra-semi',
+                              '-Wundefined-func-template',
                               '-Wno-unused-local-typedef', # Bugs #2657 and #3209
                               ]
+        version = tuple(int(i) for i in conf.env['CC_VERSION'])
+        if version < (3, 9, 0) or (Utils.unversioned_sys_platform() == 'darwin' and version < (9, 0, 0)):
+            flags['CXXFLAGS'] += ['-Wno-unknown-pragmas']
         return flags
diff --git a/daemon/table/name-tree.cpp b/daemon/table/name-tree.cpp
index 1550e3d..db0e3ff 100644
--- a/daemon/table/name-tree.cpp
+++ b/daemon/table/name-tree.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -179,26 +179,6 @@
   return nullptr;
 }
 
-template<typename ENTRY>
-Entry*
-NameTree::findLongestPrefixMatch(const ENTRY& tableEntry, const EntrySelector& entrySelector) const
-{
-  const Entry* nte = this->getEntry(tableEntry);
-  BOOST_ASSERT(nte != nullptr);
-  return this->findLongestPrefixMatch(*nte, entrySelector);
-}
-
-template Entry*
-NameTree::findLongestPrefixMatch<fib::Entry>(const fib::Entry&, const EntrySelector&) const;
-
-template Entry*
-NameTree::findLongestPrefixMatch<measurements::Entry>(const measurements::Entry&,
-                                                      const EntrySelector&) const;
-
-template Entry*
-NameTree::findLongestPrefixMatch<strategy_choice::Entry>(const strategy_choice::Entry&,
-                                                         const EntrySelector&) const;
-
 Entry*
 NameTree::findLongestPrefixMatch(const pit::Entry& pitEntry, const EntrySelector& entrySelector) const
 {
diff --git a/daemon/table/name-tree.hpp b/daemon/table/name-tree.hpp
index c4b8b27..b5bcc2b 100644
--- a/daemon/table/name-tree.hpp
+++ b/daemon/table/name-tree.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -59,9 +59,9 @@
   /** \return name tree entry on which a table entry is attached,
    *          or nullptr if the table entry is detached
    */
-  template<typename ENTRY>
+  template<typename EntryT>
   Entry*
-  getEntry(const ENTRY& tableEntry) const
+  getEntry(const EntryT& tableEntry) const
   {
     return Entry::get(tableEntry);
   }
@@ -142,15 +142,20 @@
                          const EntrySelector& entrySelector = AnyEntry()) const;
 
   /** \brief equivalent to .findLongestPrefixMatch(getEntry(tableEntry)->getName(), entrySelector)
-   *  \tparam ENTRY fib::Entry or measurements::Entry or strategy_choice::Entry
+   *  \tparam EntryT fib::Entry or measurements::Entry or strategy_choice::Entry
    *  \note This overload is more efficient than
    *        .findLongestPrefixMatch(const Name&, const EntrySelector&) in common cases.
    *  \warning Undefined behavior may occur if tableEntry is not attached to this name tree.
    */
-  template<typename ENTRY>
+  template<typename EntryT>
   Entry*
-  findLongestPrefixMatch(const ENTRY& tableEntry,
-                         const EntrySelector& entrySelector = AnyEntry()) const;
+  findLongestPrefixMatch(const EntryT& tableEntry,
+                         const EntrySelector& entrySelector = AnyEntry()) const
+  {
+    const Entry* nte = this->getEntry(tableEntry);
+    BOOST_ASSERT(nte != nullptr);
+    return this->findLongestPrefixMatch(*nte, entrySelector);
+  }
 
   /** \brief equivalent to .findLongestPrefixMatch(pitEntry.getName(), entrySelector)
    *  \note This overload is more efficient than
diff --git a/rib/readvertise/readvertise-destination.hpp b/rib/readvertise/readvertise-destination.hpp
index 1bfaeb7..d909026 100644
--- a/rib/readvertise/readvertise-destination.hpp
+++ b/rib/readvertise/readvertise-destination.hpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -53,7 +53,7 @@
   isAvailable() const
   {
     return m_isAvailable;
-  };
+  }
 
 protected:
   void
diff --git a/tests/tools/nfdc/status-fixture.hpp b/tests/tools/nfdc/status-fixture.hpp
index b955f7a..8c9eb3c 100644
--- a/tests/tools/nfdc/status-fixture.hpp
+++ b/tests/tools/nfdc/status-fixture.hpp
@@ -48,7 +48,7 @@
   operator()(Face&, KeyChain&) const
   {
     return make_unique<ValidatorNull>();
-  };
+  }
 };
 
 /** \brief fixture to test status fetching routines in a \p Module
diff --git a/tools/ndn-autoconfig/main.cpp b/tools/ndn-autoconfig/main.cpp
index fad4933..b7340a3 100644
--- a/tools/ndn-autoconfig/main.cpp
+++ b/tools/ndn-autoconfig/main.cpp
@@ -38,6 +38,11 @@
 #include <ndn-cxx/util/scheduler-scoped-event-id.hpp>
 #include <ndn-cxx/util/time.hpp>
 
+// suppress warning caused by boost::program_options::parse_config_file
+#ifdef __clang__
+#pragma clang diagnostic ignored "-Wundefined-func-template"
+#endif
+
 namespace ndn {
 namespace tools {
 namespace autoconfig {