Bad comments are bad. For example comments which only explains what can be trivially seen from the code, the classical example being:
// increment x by one
x++;
Comments which explains something which could be made clear by renaming a variable or method or otherwise restructuring the code, is a code smell:
// data1 is the collection of tasks which failed during execution
var data1 = getData1();
These are the kind of comments Martin rails against. The comment is a symptom of a failure to write clear code - in this case to use self-explanatory names for variables and methods. The comment itself is of course not the problem, the problem is we need the comment to understand the code.
But comments should be used to explain everything which is not obvious from the code, e.g. why the code is written a certain non-obvious way:
// need to reset foo before calling bar due to a bug in the foo component.
foo.reset()
foo.bar();
Comments which explains what an overly convoluted piece of code does is also a smell, but the fix is not to outlaw comments, the fix is the fix the code! In the real word, convoluted code does happen (hopefully only temporarily until a refactor) but no ordinary developer writes perfect clean code the first time. When convoluted code happens it is much better to write a comment explaining what it does than not write a comment. This comment will also make it easier to refactor later.
Sometimes code is unavoidably complex. It may be an complicated algorithm, or it may be code sacrificing clarity for performance reasons. Again comments are necessary.